home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------
-
- message.c
-
- This module handles message windows.
-
- Copyright © 1994-1995, Northwestern University.
-
- ----------------------------------------------------------------------------*/
-
- #include <string.h>
- #include <stdio.h>
-
- #include <Icons.h>
-
- #include "glob.h"
- #include "message.h"
- #include "dialog.h"
- #include "header.h"
- #include "menus.h"
- #include "print.h"
- #include "strutil.h"
- #include "wind.h"
- #include "send.h"
- #include "newswatcher.h"
- #include "url.h"
- #include "tescroll.h"
- #include "drawutil.h"
- #include "memutil.h"
- #include "windutil.h"
- #include "teutil.h"
- #include "article.h"
- #include "fileutil.h"
- #include "sfutil.h"
- #include "prefs.h"
- #include "resutil.h"
- #include "iconutil.h"
- #include "listutil.h"
- #include "dragutil.h"
- #include "group.h"
- #include "status.h"
- #include "key.h"
- #include "ic.h"
- #include "help.h"
-
-
-
- #define kTooManyGroupsDlg 145
- #define kMessageFileExistsAlert 148
- #define kAskSendOrSaveAlert 134
-
- #define kSendButtonID 500 /* Rsrc id of Send button control */
- #define kTabCheckboxID 501 /* Rsrc id of tab stops checkbox control */
- #define kWrapCheckboxID 502 /* Rsrc id of wrap checkbox control */
-
- #define kSendButtonTopNoLabels 9 /* top coord of send button if no icon labels */
- #define kSendButtonTopLabels 16 /* top coord of send button if icon labels */
-
- #define kNewsIconID 200 /* Resource id of news icon family */
- #define kMailIconID 201 /* Resource id of mail icon family */
- #define kSelfIconID 202 /* Resource id of self icon family */
-
- #define kIconV 3 /* top coord of icons */
- #define kNewsIconH 30 /* left coord of news icon */
- #define kMailIconH 110 /* left coord of mail icon */
- #define kSelfIconH 195 /* left coord of self icon */
- #define kCheckMarkV 25 /* bot coord of check mark */
- #define kCheckMarkDeltaH 16 /* offset from left coord of check mark to left
- coord of icon */
-
- #define kOptionsPanelLeftMargin 10 /* left margin for options panel controls */
-
- #define kMaxFields 15 /* max number of TE fields in window */
-
- #define kMinWindowWidth 320 /* minimum window width */
-
- #define kQuoteStringResID 128 /* 'TEXT' resource ids for saved message files */
- #define kNewsgroupsResID 129
- #define kToResID 130
- #define kSubjectResID 131
- #define kCcResID 132
- #define kBccResID 133
- #define kReplytoResID 134
- #define kFollowuptoResID 135
- #define kKeywordsResID 136
- #define kDistributionResID 137
- #define kExtraNewsResID 138
- #define kExtraMailResID 139
- #define kSignatureResID 140
- #define kReferencesResID 141
- #define kFromResID 142
-
-
-
- #pragma options align=mac68k
- typedef struct TMiscMessageWindowInfo {
- Boolean newsIcon; /* true if news icon checked */
- Boolean mailIcon; /* true if mail icon checked */
- Boolean selfIcon; /* true if self icon checked */
- Boolean tabEnabled; /* true if body tabs currently enabled for this window */
- Boolean wrapOnSend; /* true to wrap message before sending it */
- short tabStops; /* current tab stops for this window */
- } TMiscMessageWindowInfo;
- #pragma options align=reset
-
-
-
- static WindowPtr gDragDestWindow; /* pointer to drag destination window */
- static TEHandle gDestField; /* current drag destination field */
- static TEHandle gFinalDestField; /* final drag destination field */
- static short gDestFieldOffset; /* current offset into drag destination field */
- static short gFinalDestFieldOffset; /* final offset into final drag destination field */
- static Handle gDragData; /* handle to drag data */
- static Boolean gDragTextCopy; /* true if text drag is copy, false if move */
- static Boolean gDragInsertTextQuoted; /* true to insert dragged text quoted */
-
- static TEClickLoopUPP gAutoScrollUPP;
- static DragTrackingHandlerUPP gHandleTrackingUPP;
- static DragReceiveHandlerUPP gHandleReceiveUPP;
- static ControlActionUPP gScrollActionUPP;
-
-
-
- /*----------------------------------------------------------------------------
- TooManyGroupsDialog
-
- Present the "too many groups" dialog.
-
- Entry: n = number of groups.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr TooManyGroupsDialog (short n)
- {
- OSErr err = noErr;
- DialogPtr dlg = nil;
- Str255 str;
- short item;
-
- err = MyGetNewDialog(kTooManyGroupsDlg, cancel, cancel, &dlg);
- if (err != noErr) return err;
- NumToString(n, str);
- ParamText(str, "\p", "\p", "\p");
- SysBeep(0);
- MyModalDialog(dlg, gDialogFilterUPP, &item);
- err = DoClose(dlg);
- if (err != noErr) return err;
- if (item == cancel) return userCanceledErr;
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- GetViewRect
-
- Compute the "view" rectangle of a message window
-
- Entry: wind = pointer to message window.
-
- Exit: *viewRect = text rectangle.
-
- The "view" rectangle is the content area of the window minus the
- panel area and the scroll bar areas.
- ----------------------------------------------------------------------------*/
-
- static void GetViewRect (WindowPtr wind, Rect *viewRect)
- {
- TWindow **info;
-
- info = (TWindow**)GetWRefCon(wind);
- *viewRect = wind->portRect;
- viewRect->top += (**info).panelHeight;
- viewRect->bottom -= 15;
- viewRect->right -= 15;
- }
-
-
-
- /*----------------------------------------------------------------------------
- GetTextRect
-
- Compute the "text" rectangle of a message window
-
- Entry: wind = pointer to message window.
-
- Exit: *textRect = text rectangle.
-
- The "text" rectangle is the view rectangle inset by kTextMargin on
- all four sides. This is the area of the window where the text is
- displayed.
- ----------------------------------------------------------------------------*/
-
- static void GetTextRect (WindowPtr wind, Rect *textRect)
- {
- GetViewRect(wind, textRect);
- InsetRect(textRect, kTextMargin, kTextMargin);
- }
-
-
-
- /*----------------------------------------------------------------------------
- InitCurField
-
- Initialize the currently active field for a message window.
-
- Entry: wind = pointer to message window.
- ----------------------------------------------------------------------------*/
-
- static void InitCurField (WindowPtr wind)
- {
- TWindow **info;
- short i;
- TMsgFieldInfo **fields, *f;
- TEHandle edit;
-
- info = (TWindow**)GetWRefCon(wind);
- fields = (**info).fields;
- for (i = 0, f = *fields; ; i++, f++) {
- edit = f->edit;
- if ((**edit).teLength == 0) {
- (**info).curField = i;
- break;
- }
- if (edit == (**info).theTE) {
- TESetSelect(0, 0, edit);
- (**info).curField = i;
- break;
- }
- }
- if (gHaveTEOutlineHilite) TEFeatureFlag(teFOutlineHilite, TEBitSet, edit);
- }
-
-
-
- /*----------------------------------------------------------------------------
- FixHeight
-
- Round down window height to an exact multiple of lines.
-
- Entry: wind = pointer to message window.
- *height = window height.
-
- Exit: *height = adjusted window height
- ----------------------------------------------------------------------------*/
-
- static void FixHeight (WindowPtr wind, short *height)
- {
- TWindow **info;
- short panelHeight, lineHeight, adjust;
-
- info = (TWindow**)GetWRefCon(wind);
- panelHeight = (**info).panelHeight;
- lineHeight = GetFontLineHeight(wind);
- adjust = panelHeight + 15 + 2*kTextMargin;
- *height = (*height - adjust) / lineHeight * lineHeight + adjust;
- }
-
-
-
- /*----------------------------------------------------------------------------
- MinHeight
-
- Compute the minimum height of a message window.
-
- Entry: wind = pointer to message window.
- ----------------------------------------------------------------------------*/
-
- static short MinHeight (WindowPtr wind)
- {
- TWindow **info;
- short lineHeight, height, extra;
-
- info = (TWindow**)GetWRefCon(wind);
- lineHeight = GetFontLineHeight(wind);
- extra = lineHeight + 15 + 2*kTextMargin;
- if (extra < 65) extra = 65 + lineHeight;
- height = (**info).panelHeight + (**info).optionsPanelHeight + extra;
- FixHeight(wind, &height);
- return height;
- }
-
-
-
- /*----------------------------------------------------------------------------
- MinWidth
-
- Compute the minimum width of a message window.
-
- Entry: wind = pointer to message window.
- ----------------------------------------------------------------------------*/
-
- static short MinWidth (WindowPtr wind)
- {
- TWindow **info;
- TEHandle field;
- short tabFieldRight, quoteStringFieldRight;
- short minWidth;
-
- info = (TWindow**)GetWRefCon(wind);
- field = (**info).tabField;
- tabFieldRight = (**field).viewRect.right;
- field = (**info).quoteStringField;
- quoteStringFieldRight = (**field).viewRect.right;
- minWidth = 10 + (tabFieldRight < quoteStringFieldRight ? quoteStringFieldRight : tabFieldRight);
- if (minWidth < kMinWindowWidth) minWidth = kMinWindowWidth;
- return minWidth;
- }
-
-
-
- /*----------------------------------------------------------------------------
- ChangeSubject
-
- Change the subject in a message window.
-
- Entry: wind = pointer to message window.
- ----------------------------------------------------------------------------*/
-
- static void ChangeSubject (WindowPtr wind)
- {
- TWindow **info;
- TEHandle edit;
- Str255 subject, title;
-
- info = (TWindow**)GetWRefCon(wind);
- if ((**info).alias != nil) return;
- edit = (**info).subjectField;
- GetDialogItemText((**edit).hText, subject);
- GetWTitle(wind, title);
- if (*subject == 0) GetPString(kStrNoSubject, subject);
- if (!EqualString(subject, title, true, true)) {
- SetWTitle(wind, subject);
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- ComputeFieldViewRect
-
- Compute the view rectangle for a TextEdit field given the destination
- rectangle.
-
- Entry: wind = pointer to message window.
- *destRect = destination rectangle.
-
- Exit: *viewRect = view rectangle.
-
- The TextEdit view rectangle is set to the destination rectangle
- clipped to the window text rectangle. If the result is empty, the view
- rectangle is set to an off-screen rectangle.
- ----------------------------------------------------------------------------*/
-
- static void ComputeFieldViewRect (WindowPtr wind, Rect *destRect, Rect *viewRect)
- {
- Rect textRect;
-
- GetTextRect(wind, &textRect);
- *viewRect = *destRect;
- if (viewRect->top < textRect.top) viewRect->top = textRect.top;
- if (viewRect->bottom > textRect.bottom) viewRect->bottom = textRect.bottom;
- if (viewRect->top >= viewRect->bottom) SetRect(viewRect, 0, 0x7700, 500, 0x77ff);
- }
-
-
-
- /*----------------------------------------------------------------------------
- AdjustLastFieldViewRect
-
- Adjust the view rectangle for the last TextEdit field in a window.
-
- Entry: wind = pointer to message window.
-
- If the view rectangle for the last TextEdit field does not extend to the
- bottom of the window's text rectangle, it is extended to reach the bottom.
- ----------------------------------------------------------------------------*/
-
- static void AdjustLastFieldViewRect (WindowPtr wind)
- {
- TWindow **info;
- TMsgFieldInfo **fields;
- short numFields;
- TEHandle lastEdit;
- Rect textRect;
-
- info = (TWindow**)GetWRefCon(wind);
- fields = (**info).fields;
- numFields = (**info).numFields;
- lastEdit = (*fields)[numFields - 1].edit;
- GetTextRect(wind, &textRect);
- if ((**lastEdit).viewRect.bottom < textRect.bottom)
- (**lastEdit).viewRect.bottom = textRect.bottom;
- }
-
-
-
- /*----------------------------------------------------------------------------
- AdjustScrollMax
-
- Adjust the scroll bar maximum value.
-
- Entry: wind = pointer to message window.
- ----------------------------------------------------------------------------*/
-
- static void AdjustScrollMax (WindowPtr wind)
- {
- TWindow **info;
- TMsgFieldInfo **fields;
- short numFields, max, windHeight, firstScrollingField;
- short top, bottom, height, lineHeight;
- Rect textRect;
-
- info = (TWindow**)GetWRefCon(wind);
- fields = (**info).fields;
- numFields = (**info).numFields;
- firstScrollingField = (**info).firstScrollingField;
- top = (*fields)[firstScrollingField].top;
- bottom = (*fields)[numFields-1].bottom;
- GetTextRect(wind, &textRect);
- windHeight = textRect.bottom - textRect.top;
- if (bottom < textRect.bottom) bottom = textRect.bottom;
- height = bottom - top;
- max = height - windHeight;
- if (max < 0) max = 0;
- lineHeight = (**(**info).theTE).lineHeight;
- SetControlMaximum((**info).vScroll, max/lineHeight);
- }
-
-
-
- /*----------------------------------------------------------------------------
- Scroll
-
- Scroll a message window.
-
- Entry: wind = pointer to message window.
- dv = number of lines to scroll.
-
- If the vertical scroll bar's refCon is non-zero, the scroll bar max value is
- adjusted after the scrolling operation. This is what you normally want.
- The only exception is when scrolling in a TrackControl action procedure,
- when you want to set the refCon to zero.
- ----------------------------------------------------------------------------*/
-
- static void Scroll (WindowPtr wind, short dv)
- {
- TWindow **info;
- TMsgFieldInfo **fields, *f;
- Rect r, destRect, viewRect, inval;
- static RgnHandle rgn = nil;
- TEHandle edit;
- short numFields, i, firstScrollingField, lineHeight;
-
- info = (TWindow**)GetWRefCon(wind);
- lineHeight = (**(**info).theTE).lineHeight;
- dv = dv * lineHeight;
- fields = (**info).fields;
- GetViewRect(wind, &r);
- InsetRect(&r, 0, kTextMargin);
- if (rgn == nil) rgn = NewRgn();
- ScrollRect(&r, 0, dv, rgn);
- InvalRgn(rgn);
- if (!((WindowPeek)wind)->hilited) {
- inval = r;
- if (dv > 0) {
- if (inval.top + dv + lineHeight < inval.bottom)
- inval.bottom = inval.top + dv + lineHeight;
- } else {
- if (inval.bottom + dv - lineHeight > inval.top)
- inval.top = inval.bottom + dv - lineHeight;
- }
- InvalRect(&inval);
- inval = r;
- if (dv > 0) {
- inval.top = inval.bottom - lineHeight;
- } else {
- inval.bottom = inval.top + lineHeight;
- }
- InvalRect(&inval);
- }
-
- SetOrigin(0, 0);
- numFields = (**info).numFields;
- firstScrollingField = (**info).firstScrollingField;
- for (i = firstScrollingField; i < numFields; i++) {
- f = &(*fields)[i];
- edit = f->edit;
- f->top += dv;
- f->bottom += dv;
- destRect = (**edit).destRect;
- OffsetRect(&destRect, 0, dv);
- ComputeFieldViewRect(wind, &destRect, &viewRect);
- (**edit).destRect = destRect;
- (**edit).viewRect = viewRect;
- }
- AdjustLastFieldViewRect(wind);
- if (GetControlReference((**info).vScroll) != 0) AdjustScrollMax(wind);
- HandleUpdate(wind);
- KillBalloon();
- }
-
-
-
- /*----------------------------------------------------------------------------
- ScrollRangeIntoView
-
- Scroll a range of characters into view, if necessary.
-
- Entry: wind = pointer to message window.
- start = starting offset of text range in current field.
- end = ending offet of text range in current field.
- ----------------------------------------------------------------------------*/
-
- static void ScrollRangeIntoView (WindowPtr wind, short start, short end)
- {
- TWindow **info;
- TMsgFieldInfo **fields;
- short curField, lineStart, lineEnd, top, lineHeight, vStart, vEnd;
- short oldScrollVal, max, dv;
- ControlHandle vScroll;
- TEHandle edit;
- Rect textRect;
- Boolean tooBig;
- short selStart, selEnd, savedClikStuff;
-
- AdjustScrollMax(wind);
- info = (TWindow**)GetWRefCon(wind);
- fields = (**info).fields;
- curField = (**info).curField;
- if (curField < (**info).firstScrollingField) return;
- vScroll = (**info).vScroll;
- edit = (*fields)[curField].edit;
-
- savedClikStuff = (**edit).clikStuff;
- selStart = (**edit).selStart;
- selEnd = (**edit).selEnd;
- if (start == end && selStart < selEnd) {
- if (start == selEnd) {
- (**edit).clikStuff = 0;
- } else if (end == selStart) {
- (**edit).clikStuff = 0xffff;
- }
- lineStart = TEScrollGetTELineNumber(start, edit);
- lineEnd = TEScrollGetTELineNumber(end, edit);
- } else if (start < end) {
- (**edit).clikStuff = 0xffff;
- lineStart = TEScrollGetTELineNumber(start, edit);
- (**edit).clikStuff = 0;
- lineEnd = TEScrollGetTELineNumber(end, edit);
- } else {
- lineStart = TEScrollGetTELineNumber(start, edit);
- lineEnd = TEScrollGetTELineNumber(end, edit);
- }
- (**edit).clikStuff = savedClikStuff;
-
- top = (**edit).destRect.top;
- lineHeight = (**edit).lineHeight;
- vStart = top + lineStart*lineHeight;
- vEnd = top + (lineEnd+1)*lineHeight;
- GetTextRect(wind, &textRect);
- tooBig = (vEnd - vStart) > (textRect.bottom - textRect.top);
- if (vEnd > textRect.bottom) {
- if (vStart < textRect.bottom - lineHeight) return;
- if (tooBig) {
- dv = textRect.top - vStart;
- } else {
- dv = textRect.bottom - vEnd;
- }
- } else if (vStart < textRect.top) {
- if (vEnd > textRect.top + lineHeight) return;
- if (tooBig) {
- dv = textRect.bottom - vEnd;
- } else {
- dv = textRect.top - vStart;
- }
- } else {
- AdjustScrollMax(wind);
- return;
- }
- dv = dv/lineHeight;
- oldScrollVal = GetControlValue(vScroll);
- max = GetControlMaximum(vScroll);
- if (oldScrollVal - dv > max) dv = oldScrollVal - max;
- Scroll(wind, dv);
- SetControlValue(vScroll, oldScrollVal - dv);
- }
-
-
-
- /*----------------------------------------------------------------------------
- ScrollSelectionIntoView
-
- Scroll the current selection into view, if necessary.
-
- Entry: wind = pointer to message window.
- ----------------------------------------------------------------------------*/
-
- static void ScrollSelectionIntoView (WindowPtr wind)
- {
- TWindow **info;
- TMsgFieldInfo **fields;
- short curField;
- TEHandle edit;
-
- info = (TWindow**)GetWRefCon(wind);
- fields = (**info).fields;
- curField = (**info).curField;
- if (curField < (**info).firstScrollingField) return;
- edit = (*fields)[curField].edit;
- ScrollRangeIntoView (wind, (**edit).selStart, (**edit).selEnd);
- }
-
-
-
- /*----------------------------------------------------------------------------
- ScrollToMiddle
-
- Scroll a given point in a field to the middle of the window, if necessary.
-
- Entry: wind = pointer to message window.
- offset = offset of character in current field to scroll to middle.
- ----------------------------------------------------------------------------*/
-
- static void ScrollToMiddle (WindowPtr wind, short offset)
- {
- TWindow **info;
- TMsgFieldInfo **fields;
- short curField;
- ControlHandle vScroll;
- TEHandle edit;
- short lineStart, top, lineHeight, vStart;
- short oldScrollVal, max, dv, textHeight;
- Rect textRect;
- short savedClikStuff;
-
- AdjustScrollMax(wind);
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- if (curField < (**info).firstScrollingField) return;
- fields = (**info).fields;
- vScroll = (**info).vScroll;
- edit = (*fields)[curField].edit;
-
- savedClikStuff = (**edit).clikStuff;
- (**edit).clikStuff = 0xffff;
- lineStart = TEScrollGetTELineNumber(offset, edit);
- (**edit).clikStuff = savedClikStuff;
- top = (**edit).destRect.top;
- lineHeight = (**edit).lineHeight;
- vStart = top + lineStart*lineHeight;
- GetTextRect(wind, &textRect);
- if (vStart >= textRect.top && vStart <= textRect.bottom - lineHeight) return;
- textHeight = (textRect.bottom - textRect.top) / lineHeight;
- dv = (textRect.top - vStart)/lineHeight + (textHeight >> 1);
- oldScrollVal = GetControlValue(vScroll);
- max = GetControlMaximum(vScroll);
- if (oldScrollVal - dv > max) dv = oldScrollVal - max;
- Scroll(wind, dv);
- SetControlValue(vScroll, oldScrollVal - dv);
- }
-
-
-
- /*----------------------------------------------------------------------------
- GetPageHeight
-
- Get the page height.
-
- Entry: wind = pointer to message window.
-
- Exit: function result = page height.
- ----------------------------------------------------------------------------*/
-
- static short GetPageHeight (WindowPtr wind)
- {
- TWindow **info;
- TEHandle theTE;
- short lineHeight;
- Rect r;
-
- info = (TWindow**)GetWRefCon(wind);
- theTE = (**info).theTE;
- lineHeight = (**theTE).lineHeight;
- GetTextRect(wind, &r);
- return (r.bottom - r.top) / lineHeight - 1;
- }
-
-
-
- /*----------------------------------------------------------------------------
- ScrollAction
-
- Scroll bar action procedure.
-
- Entry: vScroll = handle to vertical scroll bar control
- part = part code.
- ----------------------------------------------------------------------------*/
-
- static pascal void ScrollAction (ControlHandle vScroll, short part)
- {
- WindowPtr wind;
- short val, max, page, dv;
-
- wind = (**vScroll).contrlOwner;
- val = (**vScroll).contrlValue;
- max = (**vScroll).contrlMax;
- page = GetPageHeight(wind);
- dv = 0;
- switch (part) {
- case inUpButton:
- dv = val > 0 ? 1 : 0;
- break;
- case inDownButton:
- dv = val < max ? -1 : 0;
- break;
- case inPageUp:
- dv = val > page ? page : val;
- break;
- case inPageDown:
- dv = val < max - page ? -page : val - max;
- break;
- case kScrollToHome:
- dv = val;
- break;
- case kScrollToEnd:
- dv = val - max;
- break;
- }
- if (dv != 0) {
- SetControlValue(vScroll, val - dv);
- Scroll(wind, dv);
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- AutoScroll
-
- Handle message window autoscrolling.
-
- Exit: function result = true
- ----------------------------------------------------------------------------*/
-
- static pascal Boolean AutoScroll (void)
- {
- WindowPtr wind;
- TWindow **info;
- ControlHandle vScroll;
- TMsgFieldInfo **fields;
- short curField;
- TEHandle edit;
- Rect r;
- Point where;
- short val, max;
-
- wind = MyFrontWindow();
- if (wind == nil) return true;
- info = (TWindow**)GetWRefCon(wind);
- vScroll = (**info).vScroll;
- fields = (**info).fields;
- curField = (**info).curField;
- edit = (*fields)[curField].edit;
- val = GetControlValue(vScroll);
- max = GetControlMaximum(vScroll);
- GetTextRect(wind, &r);
- GetMouse(&where);
- ClipRect(&wind->portRect);
- if (where.v < r.top && val > 0) {
- Scroll(wind, 1);
- SetControlValue(vScroll, val-1);
- } else if (where.v > r.bottom && val < max) {
- Scroll(wind, -1);
- SetControlValue(vScroll, val+1);
- }
- r = (**edit).viewRect;
- ClipRect(&r);
- return true;
- }
-
-
-
- /*----------------------------------------------------------------------------
- AddFieldInfo
-
- Add one new field to array of field info.
-
- Entry: wind = pointer to message window.
- edit = handle to TextEdit record.
- sepLine = true if field preceeded by gray separator line.
- labelKind = kind of label for this field.
- labelIndex = index in STR# 128 of field label, or 0 if none.
- ----------------------------------------------------------------------------*/
-
- static void AddFieldInfo (WindowPtr wind, TEHandle edit, Boolean sepLine,
- TMsgFieldLabelKind labelKind, short labelIndex)
- {
- TWindow **info;
- short index;
- TMsgFieldInfo **fields;
- TMsgFieldInfo f;
- short nLines;
- short lineHeight, height, h;
- static short v;
- Rect textRect, destRect, viewRect;
- Str255 label;
-
- if (labelIndex > 0) GetPString(labelIndex, label);
- info = (TWindow**)GetWRefCon(wind);
- index = (**info).numFields;
- fields = (**info).fields;
- f.edit = edit;
- f.sepLine = sepLine;
- f.labelKind = labelKind;
- if (labelIndex > 0) BlockMoveData(label, f.label, *label+1);
-
- if (index == (**info).firstScrollingField) v = (**info).panelHeight + kTextMargin;
- f.top = v;
- lineHeight = (**edit).lineHeight;
- if (sepLine) v += lineHeight;
- switch (labelKind) {
- case kNoMsgFieldLabel:
- h = kTextMargin;
- break;
- case kMsgFieldLabelLeft:
- h = (**info).labelRight;
- break;
- case kMsgFieldLabelTop:
- h = kTextMargin;
- v += lineHeight;
- break;
- }
- GetTextRect(wind, &textRect);
- SetRect(&destRect, h, v, textRect.right, v + 1000);
- (**edit).viewRect = (**edit).destRect = destRect;
- TECalText(edit);
- f.nLines = nLines = TEScrollNumTELines(edit);
- height = nLines * lineHeight;
- v += height;
- destRect.bottom = f.bottom = v;
- ComputeFieldViewRect(wind, &destRect, &viewRect);
- (**edit).viewRect = viewRect;
- (**edit).destRect = destRect;
- (*fields)[index] = f;
- (**info).numFields++;
- KillBalloon();
- }
-
-
-
- /*----------------------------------------------------------------------------
- RebuildFields
-
- Rebuild the field info for a message window.
-
- Entry: wind = pointer to message window.
- ----------------------------------------------------------------------------*/
-
- static void RebuildFields (WindowPtr wind)
- {
- TWindow **info;
- TMsgFieldInfo **fields;
-
- info = (TWindow**)GetWRefCon(wind);
- fields = (**info).fields;
-
- if ((**info).showDetails) {
- (*fields)[0].edit = (**info).tabField;
- (*fields)[1].edit = (**info).quoteStringField;
- (**info).firstScrollingField = (**info).numFields = 2;
- } else {
- (**info).firstScrollingField = (**info).numFields = 0;
- }
- if ((**info).newsIcon) {
- AddFieldInfo(wind, (**info).newsgroupsField, false, kMsgFieldLabelLeft,
- kStrNewsgroups);
- }
- if ((**info).mailIcon) {
- AddFieldInfo(wind, (**info).toField, false, kMsgFieldLabelLeft,
- kStrTo);
- }
- AddFieldInfo(wind, (**info).subjectField, false, kMsgFieldLabelLeft,
- kStrSubject);
- if ((**info).showDetails) {
- if ((**info).mailIcon) {
- AddFieldInfo(wind, (**info).ccField, false, kMsgFieldLabelLeft,
- kStrCc);
- AddFieldInfo(wind, (**info).bccField, false, kMsgFieldLabelLeft,
- kStrBcc);
- }
- AddFieldInfo(wind, (**info).replytoField, false, kMsgFieldLabelLeft,
- kStrReplyto);
- if ((**info).newsIcon) {
- AddFieldInfo(wind, (**info).followuptoField, false, kMsgFieldLabelLeft,
- kStrFollowupto);
- }
- AddFieldInfo(wind, (**info).keywordsField, false, kMsgFieldLabelLeft,
- kStrKeywords);
- if ((**info).newsIcon) {
- AddFieldInfo(wind, (**info).distributionField, false, kMsgFieldLabelLeft,
- kStrDistribution);
- AddFieldInfo(wind, (**info).extraNewsField, true, kMsgFieldLabelTop,
- kStrExtraNewsHeaderLines);
- }
- if ((**info).mailIcon) {
- AddFieldInfo(wind, (**info).extraMailField, true, kMsgFieldLabelTop,
- kStrExtraMailHeaderLines);
- }
- AddFieldInfo(wind, (**info).theTE, true, kMsgFieldLabelTop,
- kStrBody);
- AddFieldInfo(wind, (**info).signatureField, true, kMsgFieldLabelTop,
- kStrSignature);
- } else {
- AddFieldInfo(wind, (**info).theTE, true, kNoMsgFieldLabel, 0);
- }
-
- AdjustLastFieldViewRect(wind);
- AdjustScrollMax(wind);
- SetControlValue((**info).vScroll, 0);
- }
-
-
-
- /*----------------------------------------------------------------------------
- ChangeDisplayedFields
-
- Change the currently displayed fields in a message window.
-
- Entry: wind = pointer to message window.
- ----------------------------------------------------------------------------*/
-
- static void ChangeDisplayedFields (WindowPtr wind)
- {
- TWindow **info;
- TMsgFieldInfo **fields, *f;
- TEHandle oldEdit, newEdit;
- short oldField, newField, numFields;
- Rect viewRect;
-
- info = (TWindow**)GetWRefCon(wind);
- fields = (**info).fields;
- oldField = (**info).curField;
- oldEdit = (*fields)[oldField].edit;
- RebuildFields(wind);
- numFields = (**info).numFields;
-
- for (newField = 0, f = *fields; newField < numFields; newField++, f++) {
- newEdit = f->edit;
- if (oldEdit == newEdit) break;
- if (newEdit == (**info).newsgroupsField ||
- newEdit == (**info).toField ||
- newEdit == (**info).subjectField)
- {
- if ((**newEdit).teLength == 0) break;
- }
- }
- if (newField >= numFields) {
- InitCurField(wind);
- newField = (**info).curField;
- newEdit = (*fields)[newField].edit;
- }
- (**info).curField = newField;
- if (newEdit != oldEdit) {
- if (gHaveTEOutlineHilite) TEFeatureFlag(teFOutlineHilite, TEBitClear, oldEdit);
- TESetSelect(0, 0, oldEdit);
- TEDeactivate(oldEdit);
- MyTEActivate(newEdit);
- if (gHaveTEOutlineHilite) TEFeatureFlag(teFOutlineHilite, TEBitSet, newEdit);
- }
- ScrollSelectionIntoView(wind);
- GetViewRect(wind, &viewRect);
- InvalRect(&viewRect);
- KillBalloon();
- }
-
-
-
- /*----------------------------------------------------------------------------
- UncheckNewsIcon
-
- Uncheck the news icon in a message window.
-
- Entry: wind = pointer to message window.
- ----------------------------------------------------------------------------*/
-
- void UncheckNewsIcon (WindowPtr wind)
- {
- TWindow **info;
- Rect r;
-
- info = (TWindow**)GetWRefCon(wind);
- (**info).newsIcon = false;
- SetRect(&r, kNewsIconH - kCheckMarkDeltaH, kIconV, kNewsIconH - 1, kIconV + 32);
- InvalRect(&r);
- ChangeDisplayedFields(wind);
- HandleUpdate(wind);
- }
-
-
-
- /*----------------------------------------------------------------------------
- ResizeContents
-
- Adjust a message window's contents after a window size change (grow
- or zoom).
-
- Entry: wind = pointer to message window.
- ----------------------------------------------------------------------------*/
-
- static void ResizeContents (WindowPtr wind)
- {
- TWindow **info;
- short width, height, panelHeight, sendButtonTop;
- ControlHandle vScroll, sendButton;
- Rect r;
-
- info = (TWindow**)GetWRefCon(wind);
- panelHeight = (**info).panelHeight;
- vScroll = (**info).vScroll;
- sendButton = (**info).sendButton;
- width = wind->portRect.right;
- height = wind->portRect.bottom;
-
- SetRect(&r, width-15, panelHeight-1, width+1, height-14);
- (**vScroll).contrlRect = r;
-
- sendButtonTop = (**info).showLabels ? kSendButtonTopLabels : kSendButtonTopNoLabels;
- SetRect(&r, width-70, sendButtonTop, width-10, sendButtonTop+20);
- (**sendButton).contrlRect = r;
-
- RebuildFields(wind);
- InvalRect(&wind->portRect);
- ScrollSelectionIntoView(wind);
- }
-
-
-
- /*----------------------------------------------------------------------------
- ChangeCurField
-
- Change the currently active field in a message window.
-
- Entry: wind = pointer to message window.
- newCurField = index in field info array of new active field.
- ----------------------------------------------------------------------------*/
-
- static void ChangeCurField (WindowPtr wind, short newCurField)
- {
- TWindow **info;
- TMsgFieldInfo **fields;
- short curField;
- TEHandle edit;
- Str255 tabStopsStr;
- long tabStops;
-
- info = (TWindow**)GetWRefCon(wind);
- fields = (**info).fields;
- curField = (**info).curField;
- edit = (*fields)[curField].edit;
- if (gHaveTEOutlineHilite) TEFeatureFlag(teFOutlineHilite, TEBitClear, edit);
- TESetSelect(0, 0, edit);
- TEDeactivate(edit);
- if (edit == (**info).subjectField) ChangeSubject(wind);
- if (edit == (**info).tabField) {
- GetDialogItemText((**edit).hText, tabStopsStr);
- StringToNum(tabStopsStr, &tabStops);
- (**info).tabStops = tabStops;
- }
- edit = (*fields)[newCurField].edit;
- MyTEActivate(edit);
- if (gHaveTEOutlineHilite) TEFeatureFlag(teFOutlineHilite, TEBitSet, edit);
- (**info).curField = newCurField;
- }
-
-
-
- /*----------------------------------------------------------------------------
- GetFieldIndex
-
- Get the index of a field in the fields array.
-
- Entry: wind = pointer to message window.
- edit = handle to TextEdit field.
-
- Exit: function result = index of field in fields array, or -1
- if not found.
- ----------------------------------------------------------------------------*/
-
- static short GetFieldIndex (WindowPtr wind, TEHandle edit)
- {
- TWindow **info;
- TMsgFieldInfo **fields;
- short numFields, i;
-
- info = (TWindow**)GetWRefCon(wind);
- fields = (**info).fields;
- numFields = (**info).numFields;
-
- for (i = 0; i < numFields; i++)
- if ((*fields)[i].edit == edit) break;
- return i < numFields ? i : -1;
- }
-
-
-
- /*----------------------------------------------------------------------------
- AdjustFieldHeight
-
- Adjust the height of a field after a field change.
-
- Entry: wind = pointer to message window.
- edit = handle to TextEdit field to adjust.
- ----------------------------------------------------------------------------*/
-
- static void AdjustFieldHeight (WindowPtr wind, TEHandle edit)
- {
- TWindow **info;
- TMsgFieldInfo **fields, *f, *g;
- short fieldIndex, i, nLines, lineHeight, numFields, v, height;
- Rect destRect, viewRect, r;
- short oldBottom, newBottom;
- char state;
- Boolean active;
-
- info = (TWindow**)GetWRefCon(wind);
- fields = (**info).fields;
- numFields = (**info).numFields;
-
- fieldIndex = GetFieldIndex(wind, edit);
- if (fieldIndex < (**info).firstScrollingField) return;
- active = ((WindowPeek)wind)->hilited;
-
- state = MyHGetState(fields);
- MyHLock(fields);
- f = &(*fields)[fieldIndex];
- nLines = TEScrollNumTELines(edit);
- oldBottom = f->bottom;
- if (nLines != f->nLines) {
- lineHeight = (**edit).lineHeight;
- f->nLines = nLines;
- v = f->top;
- for (i = fieldIndex, g = f; i < numFields; i++, g++) {
- edit = g->edit;
- g->top = v;
- if (g->sepLine) v += lineHeight;
- if (g->labelKind == kMsgFieldLabelTop) v += lineHeight;
- height = g->nLines * lineHeight;
- destRect = (**edit).destRect;
- destRect.top = v;
- destRect.bottom = v + height;
- ComputeFieldViewRect(wind, &destRect, &viewRect);
- v += height;
- g->bottom = v;
- (**edit).viewRect = viewRect;
- (**edit).destRect = destRect;
- }
- AdjustLastFieldViewRect(wind);
- newBottom = f->bottom;
- if (active) {
- GetViewRect(wind, &r);
- r.top = oldBottom < newBottom ? oldBottom : newBottom;
- InvalRect(&r);
- HandleUpdate(wind);
- }
- AdjustScrollMax(wind);
- KillBalloon();
- }
- MyHSetState(fields, state);
- ScrollSelectionIntoView(wind);
- if (!active) {
- GetViewRect(wind, &viewRect);
- InvalRect(&viewRect);
- HandleUpdate(wind);
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- AdjustCurFieldHeight
-
- Adjust the height of the current field after a field change.
-
- Entry: wind = pointer to message window.
- ----------------------------------------------------------------------------*/
-
- static void AdjustCurFieldHeight (WindowPtr wind)
- {
- TWindow **info;
- TMsgFieldInfo **fields;
- TEHandle edit;
- short curField;
-
- info = (TWindow**)GetWRefCon(wind);
- fields = (**info).fields;
- curField = (**info).curField;
- if (curField < (**info).firstScrollingField) return;
- edit = (*fields)[curField].edit;
- AdjustFieldHeight(wind, edit);
- }
-
-
-
- /*----------------------------------------------------------------------------
- InitializeGroupList
-
- Initialize the group list for a new message window.
-
- Entry: wind = pointer to active window, or nil if none.
- newsgroups = handle to "Newsgroups" textedit field.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr InitializeGroupList (WindowPtr wind, TEHandle newsgroups)
- {
- TWindow **info, **parentInfo;
- ListHandle theList;
- TGroup **groupArray;
- Point theCell;
- short numSelected, cellDataLen, index;
- CStr255 groupsStr;
- TWindowKind kind;
- OSErr err = noErr;
-
- kind = GetMyWindowKind(wind);
- if (kind == kNotOurWind) return noErr;
- info = (TWindow**)GetWRefCon(wind);
- switch (kind) {
- case kGroup:
- theList = (**info).theList;
- groupArray = (**info).groupArray;
- SetPt(&theCell, 0, 0);
- numSelected = 0;
- while (LGetSelect(true, &theCell, theList)) {
- numSelected++;
- if (numSelected > 50) {
- ErrorMessageNumber(kStrTooManyGroups);
- return userCanceledErr;
- }
- cellDataLen = 2;
- LGetCell(&index, &cellDataLen, theCell, theList);
- strcpy(groupsStr, *gGroupNames + (*groupArray)[index].nameOffset);
- theCell.v++;
- if (numSelected > 1) TEInsert(", ", 2, newsgroups);
- TEInsert(groupsStr, strlen(groupsStr), newsgroups);
- }
- if (numSelected > 5) {
- err = TooManyGroupsDialog(numSelected);
- if (err != noErr) return err;
- }
- break;
- case kSubject:
- strcpy(groupsStr, *gGroupNames + (**info).groupNameOffset);
- err = MyTESetText(groupsStr, strlen(groupsStr), newsgroups);
- if (err != noErr) return err;
- break;
- case kArticle:
- if ((**info).parentWindow != nil) {
- parentInfo = (TWindow**)GetWRefCon((**info).parentWindow);
- strcpy(groupsStr, *gGroupNames + (**parentInfo).groupNameOffset);
- }
- err = MyTESetText(groupsStr, strlen(groupsStr), newsgroups);
- if (err != noErr) return err;
- break;
- }
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DrawIcon
-
- Draw a single icon and checkmark in a message window panel area.
-
- Entry: h = horizontal coord of icon.
- id = resource id of icon family.
- checked = true to draw check mark.
- showLabel = true to draw label under icon.
- labelIndex = index in STR# 128 resource of label.
- ----------------------------------------------------------------------------*/
-
- static void DrawIcon (short h, short id, Boolean checked, Boolean showLabel,
- short labelIndex)
- {
- Rect iconRect;
- TextStyle savedStyle;
- Str255 label;
- short labelWidth;
-
- SetRect(&iconRect, h, kIconV, h+32, kIconV+32);
- PlotIconID(&iconRect, 0, ttNone, id);
- GetPortTextStyle(&savedStyle);
- if (checked) {
- TextFont(systemFont);
- TextSize(12);
- TextFace(bold);
- MoveTo(h - kCheckMarkDeltaH, kCheckMarkV);
- DrawChar(checkMark);
- }
- if (showLabel) {
- GetPString(labelIndex, label);
- TextFont(applFont);
- TextSize(9);
- TextFace(0);
- labelWidth = StringWidth(label);
- MoveTo(h + 13 - (labelWidth >> 1), kIconV + 40);
- DrawString(label);
- }
- SetPortTextStyle(&savedStyle);
- }
-
-
-
- /*----------------------------------------------------------------------------
- QuoteText
-
- Quote article text.
-
- Entry: text = handle to text.
- start = beginning position in text to quote.
- end = ending position in text to quote.
-
- Exit: function result = error code.
- text = handle to quoted text.
-
- The quote string is inserted at the beginning of each line in the
- range [start, end).
- ----------------------------------------------------------------------------*/
-
- static OSErr QuoteText (Handle text, long start, long end)
- {
- long oldLen, len, deltaLen, quoteStringLen;
- char *p, *pEnd, *q;
- OSErr err = noErr;
-
- quoteStringLen = strlen(gPrefs.quoteString);
- oldLen = MyGetHandleSize(text);
- deltaLen = 0;
- for (p = *text + start, pEnd = *text + end; p < pEnd; p++)
- if (*p == CR) deltaLen += quoteStringLen;
- if (start < end && *(*text + end - 1) != CR) deltaLen += quoteStringLen;
- len = oldLen + deltaLen;
-
- err = MySetHandleSize(text, len);
- if (err != noErr) return err;
-
- BlockMoveData(*text + start, *text + start + deltaLen, oldLen - start);
-
- p = *text + start + deltaLen;
- pEnd = *text + end + deltaLen;
- q = *text + start;
- while (p < pEnd) {
- BlockMoveData(gPrefs.quoteString, q, quoteStringLen);
- q += quoteStringLen;
- while (p < pEnd && *p != CR) *q++ = *p++;
- p++;
- if (p < pEnd) *q++ = CR;
- }
-
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- MoveHeaderLine
-
- Move a header line from a text block to a TextEdit field.
-
- Entry: text = handle to text block.
- key = header keyword.
- field = handle to TextEdit field.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
-
- static OSErr MoveHeaderLine (Handle text, char *key, TEHandle field)
- {
- Handle header;
- OSErr err = noErr;
-
- err = FindHeaderHandle(text, key, &header);
- if (err != noErr) return err;
- if (header == nil) return noErr;
- MyDisposeHandle((**field).hText);
- (**field).hText = header;
- DeleteHeaderLine(text, key);
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- InitFieldInfo
-
- Initialize field info for a new message window.
-
- Entry: wind = pointer to message window.
- ----------------------------------------------------------------------------*/
-
- static void InitFieldInfo (WindowPtr wind)
- {
- TWindow **info;
- short maxWidth, width;
- Str255 str;
-
- info = (TWindow**)GetWRefCon(wind);
-
- GetPString(kStrNewsgroups, str);
- maxWidth = StringWidth(str);
- GetPString(kStrTo, str);
- width = StringWidth(str);
- if (width > maxWidth) maxWidth = width;
- GetPString(kStrSubject, str);
- width = StringWidth(str);
- if (width > maxWidth) maxWidth = width;
- GetPString(kStrCc, str);
- width = StringWidth(str);
- if (width > maxWidth) maxWidth = width;
- GetPString(kStrBcc, str);
- width = StringWidth(str);
- if (width > maxWidth) maxWidth = width;
- GetPString(kStrReplyto, str);
- width = StringWidth(str);
- if (width > maxWidth) maxWidth = width;
- GetPString(kStrFollowupto, str);
- width = StringWidth(str);
- if (width > maxWidth) maxWidth = width;
- GetPString(kStrKeywords, str);
- width = StringWidth(str);
- if (width > maxWidth) maxWidth = width;
- GetPString(kStrDistribution, str);
- width = StringWidth(str);
- if (width > maxWidth) maxWidth = width;
-
- (**info).labelRight = maxWidth + kTextMargin + 4;
-
- RebuildFields(wind);
- InitCurField(wind);
- }
-
-
-
- /*----------------------------------------------------------------------------
- MyTENew
-
- Create a TexTedit record.
-
- Exit: function result = handle to new TE record.
- ----------------------------------------------------------------------------*/
-
- static TEHandle MyTENew (void)
- {
- Rect r;
- TEHandle edit;
-
- SetRect(&r, 0, 0x7700, 500, 0x7fff);
- edit = TENew(&r, &r);
- (**edit).clickLoop = gAutoScrollUPP;
- return edit;
- }
-
-
-
- /*----------------------------------------------------------------------------
- InsertText
-
- Insert new text (pasted or dragged) into a field.
-
- Entry: wind = pointer to message window
- text = handle to text to insert.
- len = length of text to insert.
- edit = handle to TextEdit field for inserted text.
- offset = offset into TextEdit field for inserted text.
- deleteCurSel = true to delete current selected text.
- quote = true to insert text quoted.
- paste = true if paste, false if drag.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr InsertText (WindowPtr wind, Handle text, long len, TEHandle edit,
- short offset, Boolean deleteCurSel, Boolean quote, Boolean paste)
- {
- TWindow **info;
- short curField;
- TMsgFieldInfo **fields;
- TEHandle curEdit, quoteStringField;
- Handle newText = nil;
- char quoteString[11];
- long quoteStringLen, maxLen, quotedTextLen, newLen;
- OSErr err = noErr;
- unsigned char *p, *pEnd, *q;
- short n, tabStops, deletedTextLen, editIndex;
- Boolean isTabField, isQuoteStringField, isBodyField, isBodyOrSigField;
- Boolean extraSpaceDeleted, extraSpaceAddedInFront;
-
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- fields = (**info).fields;
- curEdit = (*fields)[curField].edit;
- quoteStringField = (**info).quoteStringField;
- tabStops = (**info).tabStops;
- isTabField = edit == (**info).tabField;
- isQuoteStringField = edit == quoteStringField;
- isBodyField = edit == (**info).theTE;
- isBodyOrSigField = isBodyField || edit == (**info).signatureField;
- if (deleteCurSel && edit == curEdit) {
- deletedTextLen = (**curEdit).selEnd - (**curEdit).selStart;
- if (offset > (**edit).selEnd) offset -= deletedTextLen;
- } else {
- deletedTextLen = 0;
- }
-
- if (len == 0) return noErr;
- if (len >= 0x8000) goto exit1;
-
- maxLen = isTabField ? 2 : isQuoteStringField ? 11 : 0x7fff;
- if (!isBodyField) quote = false;
-
- newLen = 0;
- n = tabStops;
- for (p = (unsigned char*)*text, pEnd = p + len; p < pEnd; p++) {
- if (isTabField && (*p < '0' || *p > '9')) goto exit3;
- if (*p == '\t' && isBodyOrSigField) {
- newLen += n;
- n = tabStops;
- } else if (isPrintable(*p) || (isBodyField && *p == FF)) {
- newLen++;
- n--;
- if (n <= 0) n = tabStops;
- } else if (*p == CR) {
- newLen++;
- n = tabStops;
- } else if (!isBodyOrSigField) {
- goto exit3;
- }
- }
-
- if ((long)(**edit).teLength - deletedTextLen + newLen > maxLen)
- {
- if (isTabField || isQuoteStringField) {
- goto exit4;
- } else {
- goto exit1;
- }
- }
-
- err = MyNewHandle(newLen, &newText);
- if (err != noErr) goto exit2;
-
- n = tabStops;
- for (p = (unsigned char*)*text, q = (unsigned char*)*newText; p < pEnd; p++) {
- if (*p == '\t' && isBodyOrSigField) {
- while (n-- > 0) *q++ = ' ';
- n = tabStops;
- } else if (isPrintable(*p) || (isBodyField && *p == FF)) {
- *q++ = *p;
- n--;
- if (n <= 0) n = tabStops;
- } else if (*p == CR) {
- *q++ = *p;
- n = tabStops;
- }
- }
-
- MyHLock(newText);
-
- if (quote) {
- quoteStringLen = (**quoteStringField).teLength;
- BlockMoveData(*(**quoteStringField).hText, quoteString, quoteStringLen);
- p = (unsigned char*)*newText;
- pEnd = p + newLen;
- while (p < pEnd) {
- q = p;
- while (q < pEnd && *q != CR) q++;
- if (q - p + quoteStringLen > 80)
- Wrap(newText, p - (unsigned char*)*newText, q - (unsigned char*)*newText);
- p = q+1;
- }
- p = (unsigned char*)*newText;
- pEnd = p + newLen;
- quotedTextLen = 0;
- while (p < pEnd) {
- quotedTextLen += quoteStringLen;
- q = p;
- while (q < pEnd && *q != CR) q++;
- if (q < pEnd) q++;
- quotedTextLen += q-p;
- p = q;
- }
- if ((long)(**edit).teLength - deletedTextLen + quotedTextLen > 0x7fff) goto exit1;
- if (deleteCurSel) TEDelete(curEdit);
- TESetSelect(offset, offset, edit);
- p = (unsigned char*)*newText;
- pEnd = p + newLen;
- while (p < pEnd) {
- TEInsert(quoteString, quoteStringLen, edit);
- q = p;
- while (q < pEnd && *q != CR) q++;
- if (q < pEnd) q++;
- TEInsert(p, q-p, edit);
- p = q;
- }
- newLen = quotedTextLen;
- } else {
- if (isTabField || isQuoteStringField) {
- if (deleteCurSel) TEDelete(curEdit);
- TESetSelect(offset, offset, edit);
- TEInsert(*newText, newLen, edit);
- } else {
- if (deleteCurSel) {
- MyTEDelete(curEdit, false, &extraSpaceDeleted);
- if (extraSpaceDeleted && edit == curEdit &&
- offset > (**edit).selEnd) offset--;
- }
- TESetSelect(offset, offset, edit);
- MyTEPaste(*newText, newLen, edit, maxLen, &extraSpaceAddedInFront);
- if (extraSpaceAddedInFront) offset++;
- }
- }
-
- if (deleteCurSel && edit != curEdit) AdjustFieldHeight(wind, curEdit);
-
- if (!paste) {
- if (edit != curEdit) {
- editIndex = GetFieldIndex(wind, edit);
- if (editIndex >= 0) ChangeCurField(wind, editIndex);
- }
- TESetSelect(offset, offset + newLen, edit);
- }
-
- MyDisposeHandle(newText);
-
- AdjustFieldHeight(wind, edit);
- (**info).changed = true;
-
- return noErr;
-
- exit1:
-
- MyDisposeHandle(newText);
- ErrorMessageNumber(paste ? kStrScrapTooBigMaxIs32767 :
- kStrDragTextTooBigMaxIs32767);
- return userCanceledErr;
-
- exit2:
-
- MyDisposeHandle(newText);
- return err;
-
- exit3:
-
- MyDisposeHandle(newText);
- ErrorMessageNumber(paste ? kStrScrapBadChar :
- kStrDragTextBadChar);
- return userCanceledErr;
-
- exit4:
-
- MyDisposeHandle(newText);
- ErrorMessageNumber(paste ? kStrScrapTooBig :
- kStrDragTextTooBig);
- return userCanceledErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- FindFieldContainingPoint
-
- Find the field containing a point.
-
- Entry: wind = pointer to message window.
- where = point in local coords.
-
- Exit: function result = handle to TextEdit field containing the
- point, or nil if none.
- *fieldIndex = index if fields array of field containg the point.
- ----------------------------------------------------------------------------*/
-
- static TEHandle FindFieldContainingPoint (WindowPtr wind, Point where, short *fieldIndex)
- {
- TWindow **info;
- short numFields;
- TMsgFieldInfo **fields, *f;
- char state;
- short i;
- TEHandle edit;
- Rect viewRect;
-
- info = (TWindow**)GetWRefCon(wind);
- numFields = (**info).numFields;
- fields = (**info).fields;
- state = MyHGetState(fields);
- MyHLock(fields);
- for (i = 0, f = *fields; i < numFields; i++, f++) {
- edit = f->edit;
- viewRect = (**edit).viewRect;
- InsetRect(&viewRect, -kTextMargin, 0);
- if (PtInRect(where, &viewRect)) break;
- }
- MyHSetState(fields, state);
- *fieldIndex = i;
- return i < numFields ? edit : nil;
- }
-
-
-
- /*----------------------------------------------------------------------------
- CanAcceptDrag
-
- Figure out whether a dragged object can be accepted by a message window.
-
- Entry: theDrag = drag reference
-
- Exit: function result = true if this object can be accepted by a
- message window.
- *textDrag = true if dragging text, false if dragging groups.
- ----------------------------------------------------------------------------*/
-
- static Boolean CanAcceptDrag (DragReference theDrag, Boolean *textDrag)
- {
- unsigned short numItems;
- ItemReference theItem;
- FlavorFlags theFlags;
- OSErr err = noErr;
- short i;
-
- CountDragItems(theDrag, &numItems);
- for (i = 1; i <= numItems; i++) {
- GetDragItemReferenceNumber(theDrag, i, &theItem);
- err = GetFlavorFlags(theDrag, theItem, kNewsWatcherSignature, &theFlags);
- if (err != noErr) break;
- }
- if (err == noErr) {
- *textDrag = false;
- return true;
- }
- for (i = 1; i <= numItems; i++) {
- GetDragItemReferenceNumber(theDrag, i, &theItem);
- err = GetFlavorFlags(theDrag, theItem, 'TEXT', &theFlags);
- if (err != noErr) return false;
- }
- *textDrag = true;
- return true;
- }
-
-
-
- /*----------------------------------------------------------------------------
- HandleTracking
-
- Drag Manager tracking handler for message windows.
-
- Entry: message = tracking message from Drag Manager.
- wind = pointer to message window.
- handlerRefCon = reference constant (nil).
- theDrag = drag reference.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static pascal OSErr HandleTracking (DragTrackingMessage message,
- WindowPtr wind, void *handlerRefCon, DragReference theDrag)
- {
- TWindow **info;
- Point where;
- DragAttributes attributes;
- static Boolean canAcceptDrag, textDrag;
- static TEHandle hiliteField;
- RgnHandle rgn = nil;
- Boolean leftSender, inSender, inSenderSelection, canAutoScroll;
- short scrollDelta;
- static short prevScrollDelta;
- static long scrollTickCount;
- Rect viewRect;
- short fieldIndex, offset;
- TEHandle destField;
- static Boolean caretDrawn;
- static long caretTime;
- long curTime;
- ControlHandle vScroll;
- short val, max;
-
- if (gLongOperation || gInDialog) return userCanceledErr;
-
- if (gDragErr != noErr) message = dragTrackingLeaveWindow;
-
- GetDragAttributes(theDrag, &attributes);
- leftSender = (attributes & dragHasLeftSenderWindow) != 0;
- inSender = (attributes & dragInsideSenderWindow) != 0;
- info = (TWindow**)GetWRefCon(wind);
-
- /* Note: Apple's "Drag and Drop Human Interface Guidelines" prohibit autoscrolling
- unless the source and destination windows are the same and the window is
- frontmost. I do not like this rule, and have deliberately broken it. I permit
- autoscrolling inactive windows during drags. */
-
- /* canAutoScroll = inSender && wind == FrontWindow();*/
- canAutoScroll = true;
-
- switch (message) {
-
- case dragTrackingEnterHandler:
-
- break;
-
- case dragTrackingEnterWindow:
-
- canAcceptDrag = CanAcceptDrag(theDrag, &textDrag);
- hiliteField = nil;
- gDestField = nil;
- gDestFieldOffset = -1;
- prevScrollDelta = 0;
- caretDrawn = false;
- break;
-
- case dragTrackingInWindow:
-
- if (!canAcceptDrag) break;
- GetDragMouse(theDrag, &where, nil);
- GlobalToLocal(&where);
- destField = FindFieldContainingPoint(wind, where, &fieldIndex);
- if (!textDrag && destField != (**info).newsgroupsField &&
- destField != (**info).followuptoField) destField = nil;
- if (destField == nil) {
- if (caretDrawn) {
- DrawTECaret(gDestFieldOffset, gDestField);
- caretDrawn = false;
- }
- if (hiliteField != nil) {
- HideDragHilite(theDrag);
- hiliteField = nil;
- }
- } else {
- if (leftSender && hiliteField != destField) {
- if (caretDrawn) {
- DrawTECaret(gDestFieldOffset, gDestField);
- caretDrawn = false;
- }
- if (hiliteField != nil) HideDragHilite(theDrag);
- rgn = NewRgn();
- viewRect = (**destField).viewRect;
- if (fieldIndex >= (**info).firstScrollingField) {
- InsetRect(&viewRect, -kTextMargin, -3);
- } else {
- InsetRect(&viewRect, -2, -2);
- }
- RectRgn(rgn, &viewRect);
- ShowDragHilite(theDrag, rgn, true);
- DisposeRgn(rgn);
- hiliteField = destField;
- }
- if (textDrag) {
- offset = MyTEGetOffset(where, destField);
- inSenderSelection = inSender && fieldIndex == (**info).curField &&
- (**destField).selStart < offset && offset < (**destField).selEnd;
- if (destField == gDestField && offset == gDestFieldOffset) {
- if (!inSenderSelection) {
- curTime = TickCount();
- if (curTime - caretTime >= GetCaretTime()) {
- DrawTECaret(gDestFieldOffset, gDestField);
- caretDrawn = !caretDrawn;
- caretTime = curTime;
- }
- }
- } else {
- if (caretDrawn) {
- DrawTECaret(gDestFieldOffset, gDestField);
- caretDrawn = false;
- }
- if (!inSenderSelection) {
- DrawTECaret(offset, destField);
- caretDrawn = true;
- caretTime = TickCount();
- }
- }
- }
- }
- gDestField = destField;
- gDestFieldOffset = offset;
-
- GetViewRect(wind, &viewRect);
- vScroll = (**info).vScroll;
- val = GetControlValue(vScroll);
- max = GetControlMaximum(vScroll);
- if (where.v < viewRect.top && val > 0) {
- scrollDelta = -1;
- } else if (where.v > viewRect.bottom && val < max) {
- scrollDelta = +1;
- } else {
- scrollDelta = 0;
- }
- if (scrollDelta == prevScrollDelta) {
- if (scrollDelta != 0 && TickCount() - scrollTickCount < 10)
- scrollDelta = 0;
- } else {
- prevScrollDelta = scrollDelta;
- scrollDelta = 0;
- scrollTickCount = TickCount();
- }
- if (scrollDelta != 0) {
- Scroll(wind, -scrollDelta);
- SetControlValue(vScroll, val + scrollDelta);
- }
-
- break;
-
- case dragTrackingLeaveWindow:
-
- if (caretDrawn) DrawTECaret(gDestFieldOffset, gDestField);
- if (hiliteField != nil) HideDragHilite(theDrag);
- hiliteField = nil;
- gDestField = nil;
- gDestFieldOffset = -1;
- prevScrollDelta = 0;
- caretDrawn = false;
- break;
-
- case dragTrackingLeaveHandler:
-
- break;
-
- }
-
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- MergeTextScrapData
-
- Merge two blocks of text scrap data.
-
- Entry: data1 = handle to first scrap data.
- data2 = handle to second scrap data.
-
- Exit: function result = error code.
- data1 = handle to merged scrap data.
- ----------------------------------------------------------------------------*/
-
- static OSErr MergeTextScrapData (Handle data1, Handle data2)
- {
- long len1, len2;
- OSErr err = noErr;
-
- len1 = MyGetHandleSize(data1);
- len2 = MyGetHandleSize(data2);
- err = MySetHandleSize(data1, len1 + len2 + 1);
- if (err != noErr) return err;
- *(*data1 + len1) = ' ';
- BlockMoveData(*data2, *data1 + len1 + 1, len2);
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- GetTextDragScrapData
-
- Get the text scrap data at the end of a drag.
-
- Entry: theDrag = drag reference.
-
- Exit: function result = error code.
- *dragData = handle to drag data.
- ----------------------------------------------------------------------------*/
-
- static OSErr GetTextDragScrapData (DragReference theDrag, Handle *dragData)
- {
- unsigned short numItems;
- ItemReference theItem;
- OSErr err = noErr;
- short i;
- Handle data = nil, itemData = nil;
-
- CountDragItems(theDrag, &numItems);
- for (i = 1; i <= numItems; i++) {
- err = GetDragItemReferenceNumber(theDrag, i, &theItem);
- if (err != noErr) goto exit;
- err = MyGetFlavorDataHandle(theDrag, theItem, 'TEXT', &itemData);
- if (err != noErr) goto exit;
- if (i == 1) {
- data = itemData;
- itemData = nil;
- } else {
- err = MergeTextScrapData(data, itemData);
- if (err != noErr) goto exit;
- MyDisposeHandle(itemData);
- itemData = nil;
- }
- }
-
- *dragData = data;
- return noErr;
-
- exit:
-
- MyDisposeHandle(data);
- MyDisposeHandle(itemData);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- HandleTextDragReceivePostProcessor
-
- Drag Manager receive handler post processor for text drags into
- message windows.
-
- Entry: gDragDestWindow = pointer to destination window.
- gFinalDestField = handle to destination TextEdit field.
- gFinalDestFieldOffset = insertion point offset in destination
- TextEdit field.
- gDragData = handle to drag data.
- gDragInsertTextQuoted = true to insert text quoted.
- gDragTextCopy = true if copy, false if move.
-
- Exit: function result = error code.
-
- Note: User interaction and network transactions are permitted in
- this function.
- ----------------------------------------------------------------------------*/
-
- static OSErr HandleTextDragReceivePostProcessor (void)
- {
- OSErr err = noErr;
- GrafPtr port;
-
- GetPort(&port);
- SetPort(gDragDestWindow);
- err = InsertText(gDragDestWindow, gDragData, MyGetHandleSize(gDragData),
- gFinalDestField, gFinalDestFieldOffset, !gDragTextCopy,
- gDragInsertTextQuoted, false);
- MyDisposeHandle(gDragData);
- gDragData = nil;
- SetPort(port);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- HandleGroupDragReceivePostProcessor
-
- Drag Manager receive handler post processor for group drags into
- message windows.
-
- Entry: gDragDestWindow = pointer to destination window.
- gFinalDestField = handle to destination TextEdit field.
- gDragData = handle to drag data.
-
- Exit: function result = error code.
-
- Note: User interaction and network transactions are permitted in
- this function.
- ----------------------------------------------------------------------------*/
-
- static OSErr HandleGroupDragReceivePostProcessor (void)
- {
- OSErr err = noErr;
- TWindow **info;
- Handle text;
- short textLen;
- CStr255 groupName;
- char *p, *pEnd;
- Boolean fieldIsAllWhiteSpace;
- GrafPtr port;
- long dataPos, firstGroupDataPos, i, groupNameLen, lenNewGroups;
- long numGroups, numNewGroups, numOldGroups, numUnreadPairs;
-
- GetPort(&port);
- SetPort(gDragDestWindow);
-
- err = CheckScrapData(gDragData);
- if (err != noErr) goto exit;
-
- info = (TWindow**)GetWRefCon(gDragDestWindow);
- text = (**gFinalDestField).hText;
- textLen = (**gFinalDestField).teLength;
-
- dataPos = 0;
-
- dataPos += sizeof(OSType); /* skip subtype */
- dataPos += 2 * sizeof(unsigned long); /* skip version numbers */
-
- numGroups = *(long*)(*gDragData + dataPos);
- dataPos += 4;
-
- firstGroupDataPos = dataPos;
-
- if (numGroups > 50) {
- ErrorMessageNumber(kStrTooManyGroups);
- goto exit;
- }
-
- numNewGroups = 0;
- lenNewGroups = 0;
- for (i = 0; i < numGroups; i++) {
- groupNameLen = *(*gDragData + dataPos);
- dataPos++;
- BlockMoveData(*gDragData + dataPos, groupName, groupNameLen);
- dataPos += groupNameLen;
- dataPos = ((dataPos + 3) >> 2) << 2;
- *(groupName + groupNameLen) = 0;
- if (!MyIsASubstringHandle(text, groupName)) {
- numNewGroups++;
- lenNewGroups += groupNameLen + 2;
- }
- dataPos += 3*sizeof(long);
- numUnreadPairs = *(long*)(*gDragData + dataPos);
- dataPos += sizeof(long);
- dataPos += numUnreadPairs * 2 * sizeof(long);
- }
-
- if (numNewGroups == 0) goto exit;
-
- numOldGroups = 0;
- p = *text;
- pEnd = p + textLen;
- while (p < pEnd && isLWSP(*p)) p++;
- fieldIsAllWhiteSpace = p >= pEnd;
- while (p < pEnd) {
- if (*p == ' ' || *p == ',') {
- while (p < pEnd && (*p == ' ' || *p == ',')) p++;
- if (p < pEnd) numOldGroups++;
- }
- p++;
- }
- if (!fieldIsAllWhiteSpace) numOldGroups++;
-
- if (numNewGroups + numOldGroups > 5) {
- err = TooManyGroupsDialog(numNewGroups + numOldGroups);
- if (err != noErr) goto exit;
- }
-
- if (textLen + lenNewGroups > 0x7fff) {
- ErrorMessageNumber(kStrGroupDragTooBigMaxIs32767);
- err = userCanceledErr;
- goto exit;
- }
-
- dataPos = firstGroupDataPos;
- TESetSelect(0x7fff, 0x7fff, gFinalDestField);
- for (i = 0; i < numGroups; i++) {
- groupNameLen = *(*gDragData + dataPos);
- dataPos++;
- BlockMoveData(*gDragData + dataPos, groupName, groupNameLen);
- dataPos += groupNameLen;
- dataPos = ((dataPos + 3) >> 2) << 2;
- *(groupName + groupNameLen) = 0;
- if (!MyIsASubstringHandle(text, groupName)) {
- if (!fieldIsAllWhiteSpace) TEInsert(", ", 2, gFinalDestField);
- fieldIsAllWhiteSpace = false;
- TEInsert(groupName, groupNameLen, gFinalDestField);
- }
- dataPos += 3*sizeof(long);
- numUnreadPairs = *(long*)(*gDragData + dataPos);
- dataPos += sizeof(long);
- dataPos += numUnreadPairs * 2 * sizeof(long);
- }
-
- (**info).changed = true;
-
- AdjustFieldHeight(gDragDestWindow, gFinalDestField);
-
- exit:
-
- MyDisposeHandle(gDragData);
- gDragData = nil;
- SetPort(port);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- HandleReceive
-
- Drag Manager receive handler for message windows.
-
- Entry: wind = pointer to message window.
- handlerRefCon = reference constant (nil).
- theDrag = drag reference.
-
- Exit: function result = error code.
-
- Note: No user interaction or network transactions are permitted in
- this function.
- ----------------------------------------------------------------------------*/
-
- static pascal OSErr HandleReceive (WindowPtr wind, void *handlerRefCon,
- DragReference theDrag)
- {
- Boolean textDrag;
- DragAttributes attributes;
- short mouseDownModifiers, mouseUpModifiers;
- TWindow **info;
- TMsgFieldInfo **fields;
- short curField, selStart, selEnd;
- TEHandle edit;
-
- if (gLongOperation || gInDialog || gDragErr != noErr ||
- gDestField == nil || !CanAcceptDrag(theDrag, &textDrag)) goto exit;
-
- gDragDestWindow = wind;
- gFinalDestField = gDestField;
-
- if (textDrag) {
- gFinalDestFieldOffset = gDestFieldOffset;
- gDragErr = GetTextDragScrapData(theDrag, &gDragData);
- if (gDragErr != noErr) goto exit;
- gDragTextCopy = true;
- GetDragAttributes(theDrag, &attributes);
- GetDragModifiers(theDrag, nil, &mouseDownModifiers, &mouseUpModifiers);
- gDragInsertTextQuoted = (mouseDownModifiers & shiftKey) != 0 ||
- (mouseUpModifiers & shiftKey) != 0;
- if ((attributes & dragInsideSenderWindow) != 0) {
- gDragTextCopy = (mouseDownModifiers & optionKey) != 0 ||
- (mouseUpModifiers & optionKey) != 0;
- info = (TWindow**)GetWRefCon(gDragDestWindow);
- fields = (**info).fields;
- curField = (**info).curField;
- edit = (*fields)[curField].edit;
- selStart = (**edit).selStart;
- selEnd = (**edit).selEnd;
- if (edit == gFinalDestField) {
- if ((gDragTextCopy && selStart < gFinalDestFieldOffset &&
- gFinalDestFieldOffset < selEnd) ||
- (!gDragTextCopy && selStart <= gFinalDestFieldOffset &&
- gFinalDestFieldOffset <= selEnd))
- {
- gDragErr = userCanceledErr;
- goto exit;
- }
- }
- }
- gDragPostProcessor = HandleTextDragReceivePostProcessor;
- } else {
- gDragErr = GetGroupDragScrapData(theDrag, &gDragData);
- if (gDragErr != noErr) goto exit;
- gDragPostProcessor = HandleGroupDragReceivePostProcessor;
- }
-
- return noErr;
-
- exit:
-
- HandleTracking(dragTrackingLeaveWindow, wind, handlerRefCon, theDrag);
- return dragNotAcceptedErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- MakeNewWindow
-
- Create and initialize a new message window.
-
- Exit: function result = error code.
- *theWindow = pointer to new window.
- ----------------------------------------------------------------------------*/
-
- static OSErr MakeNewWindow (WindowPtr *theWindow)
- {
- short width, height;
- WindowPtr wind = nil;
- GrafPtr port;
- TWindow **info;
- Rect r;
- TEHandle signatureField, tabField, quoteStringField;
- short sigLen, panelHeight, optionsPanelHeight, lineHeight, lineHeightDiv2;
- short iconPanelHeight;
- OSErr err = noErr;
- ControlHandle vScroll, sendButton, tabCheckbox, wrapCheckbox;
- Str255 title;
- Str255 tabStopsStr, quoteStr, contrlTitle;
- CStr255 tabStopsValueStr;
- short optionsDeltaV, top, tabCheckboxLength, wrapCheckboxLength;
- short optionsSecondColLeft, sendButtonTop;
- TMsgFieldInfo **fields;
-
- MyICReadSharedPrefs(kICSignature);
- MyICReadSharedPrefs(kICMailHeaders);
- MyICReadSharedPrefs(kICNewsHeaders);
- MyICReadSharedPrefs(kICScreenFont);
-
- GetPort(&port);
-
- GetPString(kStrNoSubject, title);
- err = CreateNewWindow(kMessage, title, gPrefs.textFont, gPrefs.textSize, &wind);
- if (err != noErr) return err;
- SetPort(wind);
-
- info = (TWindow**)GetWRefCon(wind);
-
- lineHeight = GetFontLineHeight(wind);
- lineHeightDiv2 = lineHeight >> 1;
- optionsDeltaV = lineHeight + 10;
- optionsPanelHeight = 2*optionsDeltaV + 6;
- optionsPanelHeight = (optionsPanelHeight + lineHeight - 1) / lineHeight * lineHeight;
- (**info).optionsPanelHeight = optionsPanelHeight;
-
- if (gPrefs.showLabelsUnderIcons) {
- (**info).showLabels = true;
- iconPanelHeight = 54;
- } else {
- iconPanelHeight = 40;
- }
- panelHeight = iconPanelHeight;
- if (gPrefs.showMsgDetails) panelHeight += optionsPanelHeight;
- (**info).panelHeight = panelHeight;
- (**info).iconPanelHeight = iconPanelHeight;
-
- top = iconPanelHeight + ((optionsPanelHeight - 2*optionsDeltaV - 3) >> 1);
- tabCheckbox = GetNewControl(kTabCheckboxID, wind);
- CopyPascalString(contrlTitle, (**tabCheckbox).contrlTitle);
- tabCheckboxLength = 2*lineHeight + StringWidth(contrlTitle);
- r.top = top;
- r.left = kOptionsPanelLeftMargin;
- r.bottom = r.top + optionsDeltaV;
- r.right = r.left + tabCheckboxLength;
- (**tabCheckbox).contrlRect = r;
- SetControlValue(tabCheckbox, gPrefs.tabEnabled ? 1 : 0);
- if (!gPrefs.showMsgDetails) HideControl(tabCheckbox);
- (**info).tabCheckbox = tabCheckbox;
- (**info).tabEnabled = gPrefs.tabEnabled;
-
- wrapCheckbox = GetNewControl(kWrapCheckboxID, wind);
- CopyPascalString(contrlTitle, (**wrapCheckbox).contrlTitle);
- wrapCheckboxLength = 2*lineHeight + StringWidth(contrlTitle);
- r.top = top + optionsDeltaV;
- r.left = kOptionsPanelLeftMargin;
- r.bottom = r.top + optionsDeltaV;
- r.right = r.left + wrapCheckboxLength;
- (**wrapCheckbox).contrlRect = r;
- SetControlValue(wrapCheckbox, gPrefs.wrapOnSend ? 1 : 0);
- if (!gPrefs.showMsgDetails) HideControl(wrapCheckbox);
- (**info).wrapCheckbox = wrapCheckbox;
- (**info).wrapOnSend = gPrefs.wrapOnSend;
-
- optionsSecondColLeft = kOptionsPanelLeftMargin + 15 +
- (tabCheckboxLength < wrapCheckboxLength ? wrapCheckboxLength : tabCheckboxLength);
- GetPString(kStrTabStops, tabStopsStr);
- r.top = top + 5;
- r.bottom = r.top + lineHeight;
- r.left = optionsSecondColLeft + StringWidth(tabStopsStr) + 2;
- r.right = r.left + 3*CharWidth('9');
- tabField = TENew(&r, &r);
- sprintf(tabStopsValueStr, "%d", gPrefs.tabStops);
- err = MyTESetText(tabStopsValueStr, strlen(tabStopsValueStr), tabField);
- if (err != noErr) goto exit;
- (**info).tabField = tabField;
- (**info).tabStops = gPrefs.tabStops;
-
- GetPString(kStrQuoteString, quoteStr);
- r.top = top + 5 + optionsDeltaV;
- r.bottom = r.top + lineHeight;
- r.left = optionsSecondColLeft + StringWidth(quoteStr) + 2;
- r.right = r.left + 12*CharWidth('9');
- quoteStringField = TENew(&r, &r);
- err = MyTESetText(gPrefs.quoteString, strlen(gPrefs.quoteString), quoteStringField);
- if (err != noErr) goto exit;
- (**info).quoteStringField = quoteStringField;
-
- width = MinWidth(wind);
- height = MinHeight(wind);
- PositionNewWindow(wind, width, height);
-
- SetRect(&r, width-15, panelHeight-1, width+1, height-14);
- vScroll = NewControl(wind, &r, "\p", true, 0, 0, 0, scrollBarProc, 1);
- (**info).vScroll = vScroll;
-
- sendButton = GetNewControl(kSendButtonID, wind);
- sendButtonTop = (**info).showLabels ? kSendButtonTopLabels : kSendButtonTopNoLabels;
- MoveControl(sendButton, width-70, sendButtonTop);
- (**info).sendButton = sendButton;
-
- (**info).selfIcon = gPrefs.copySelf;
- (**info).showDetails = gPrefs.showMsgDetails;
-
- (**info).theTE = MyTENew();
- (**info).newsgroupsField = MyTENew();
- (**info).toField = MyTENew();
- (**info).subjectField = MyTENew();
- (**info).ccField = MyTENew();
- (**info).bccField = MyTENew();
- (**info).replytoField = MyTENew();
- (**info).followuptoField = MyTENew();
- (**info).keywordsField = MyTENew();
- (**info).distributionField = MyTENew();
-
- (**info).extraNewsField = MyTENew();
- TEInsert(gPrefs.extraNewsHdrLines, strlen(gPrefs.extraNewsHdrLines),
- (**info).extraNewsField);
-
- (**info).extraMailField = MyTENew();
- TEInsert(gPrefs.extraMailHdrLines, strlen(gPrefs.extraMailHdrLines),
- (**info).extraMailField);
-
- signatureField = MyTENew();
- sigLen = strlen(gPrefs.signature);
- if (sigLen > 0) {
- if (gPrefs.addSigBlankLine) TEInsert(CRSTR, 1, signatureField);
- if (gPrefs.addSigSeparatorLine) TEInsert("-- \r", 4, signatureField);
- TEInsert(gPrefs.signature, sigLen, signatureField);
- }
- (**info).signatureField = signatureField;
-
- err = MyNewHandle(kMaxFields * sizeof(TMsgFieldInfo), &fields);
- if (err != noErr) goto exit;
- (**info).fields = fields;
-
- if (gHaveDragMgr) {
- err = InstallTrackingHandler(gHandleTrackingUPP, wind, nil);
- if (err != noErr) goto exit;
- err = InstallReceiveHandler(gHandleReceiveUPP, wind, nil);
- if (err != noErr) goto exit;
- }
-
- *theWindow = wind;
- SetPort(port);
- return noErr;
-
- exit:
-
- DoClose(wind);
- SetPort(port);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- BuildReplyBody
-
- Build the body of a reply message.
-
- Entry: text = handle to full article text.
- quoteText = handle to text to be quoted, or nil to quote the
- full text.
- start = offset in quoteText of beginning of text to
- be quoted.
- end = offset in quoteText of end of text to be quoted.
- messageid = handle to article message id.
- from = handle to message "from" header line.
- body = handle.
-
- Exit: function result = error code.
- body = handle to reply body.
- ----------------------------------------------------------------------------*/
-
- static OSErr BuildReplyBody (Handle text, Handle quoteText, long start,
- long end, Handle messageid, Handle from, Handle body)
- {
- long len, messageidLen, fromLen, quoteStart;
- long len1, len2, len3;
- char *q;
- OSErr err = noErr;
- CStr255 quoteStr1, quoteStr2, quoteStr3;
-
- if (quoteText == nil) {
- quoteText = text;
- start = FindBody(quoteText);
- end = MyGetHandleSize(text);
- }
-
- messageidLen = messageid == nil ? 0 : MyGetHandleSize(messageid);
- fromLen = from == nil ? 0 : MyGetHandleSize(from);
- GetCString(kStrQuoteStr1, quoteStr1);
- GetCString(kStrQuoteStr2, quoteStr2);
- GetCString(kStrQuoteStr3, quoteStr3);
- len1 = strlen(quoteStr1);
- len2 = strlen(quoteStr2);
- len3 = strlen(quoteStr3);
- quoteStart = len1 + messageidLen + len2 + fromLen + len3 + 2;
- len = quoteStart + end - start;
-
- err = MySetHandleSize(body, len);
- if (err != noErr) return err;
-
- q = *body;
- BlockMoveData(quoteStr1, q, len1);
- q += len1;
- if (messageid != nil) {
- BlockMoveData(*messageid, q, messageidLen);
- q += messageidLen;
- }
- BlockMoveData(quoteStr2, q, len2);
- q += len2;
- if (from != nil) {
- BlockMoveData(*from, q, fromLen);
- q += fromLen;
- }
- BlockMoveData(quoteStr3, q, len3);
- q += len3;
- *q++ = CR;
- *q++ = CR;
- BlockMoveData(*quoteText + start, q, end - start);
-
- err = QuoteText(body, quoteStart, len);
- if (err != noErr) return err;
-
- len = MyGetHandleSize(body);
- if (len > 0x7fff) {
- MySetHandleSize(body, 0x7fff);
- ErrorMessageNumber(kStrTrunc);
- }
-
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- FoldReferences
-
- Fold the "References" header line.
-
- Entry: references = handle to references.
-
- Exit: function result = error code.
- references = handle to folded references.
- ----------------------------------------------------------------------------*/
-
- static OSErr FoldReferences (Handle references)
- {
- long numFolds = 0;
- char *p, *pEnd, *q;
- long len, newLen;
- OSErr err = noErr;
-
- /* Unfortunately, INN 1.4 doesn't understand folded References header
- lines. Also, Rich Salz recommended limiting them to 1K. So this
- function just truncates to 1K instead of doing folding. The code
- is still present, just inactive, so if we ever want to turn it on
- we can. */
-
- {
- len = MyGetHandleSize(references);
- if (len < 1000) return noErr;
- pEnd = *references + len;
- p = pEnd - 999;
- while (p < pEnd && *p != '<') p++;
- newLen = pEnd - p;
- BlockMoveData(p, *references, newLen);
- MySetHandleSize(references, newLen);
- return noErr;
- }
-
- len = MyGetHandleSize(references);
-
- p = *references;
- pEnd = *references + len;
- while (p < pEnd) {
- if (isLWSP(*p)) {
- numFolds++;
- p++;
- while (p < pEnd && isLWSP(*p)) p++;
- } else {
- p++;
- }
- }
-
- newLen = len + 3*numFolds;
- err = MySetHandleSize(references, newLen);
- if (err != noErr) return err;
-
- BlockMoveData(*references, *references + newLen - len, len);
-
- p = *references + newLen - len;
- pEnd = *references + newLen;
- q = *references;
- while (p < pEnd) {
- if (isLWSP(*p)) {
- *q++= CR;
- *q++ = ' ';
- *q++ = ' ';
- *q++ = ' ';
- p++;
- while (p < pEnd && isLWSP(*p)) p++;
- } else {
- *q++ = *p++;
- }
- }
-
- MySetHandleSize(references, q - *references);
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- OpenReplyWindow
-
- Open a reply window.
-
- Entry: text = handle to full article text.
- quoteText = handle to text to be quoted, or nil to quote the
- full text.
- start = offset in quoteText of beginning of text to
- be quoted.
- end = offset in quoteText of end of text to be quoted.
- reverseIcons = true to reverse the normal settings of the news
- and mail icons.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr OpenReplyWindow (Handle text, Handle quoteText, long start, long end,
- Boolean reverseIcons)
- {
- WindowPtr wind = nil;
- TWindow **info;
- Handle newsgroups = nil;
- Handle subject = nil;
- Handle followupto = nil;
- Handle from = nil;
- Handle replyto = nil;
- Handle references = nil;
- Handle messageid = nil;
- Handle distribution = nil;
- OSErr err = noErr;
- Boolean followuptoPoster = false;
- long subjectLen, newSubjectLen;
- long refLen, idLen, newRefLen, oldReLen;
- Handle newReferences;
- TEHandle theTE, newsgroupsField, toField, subjectField, distributionField;
- Handle hText;
- short i, iEnd;
- GrafPtr port;
-
- GetPort(&port);
-
- err = FindHeaderHandle(text, "Newsgroups", &newsgroups);
- if (err != noErr) goto exit;
- err = FindHeaderHandle(text, "Subject", &subject);
- if (err != noErr) goto exit;
- err = FindHeaderHandle(text, "Followup-To", &followupto);
- if (err != noErr) goto exit;
- err = FindHeaderHandle(text, "From", &from);
- if (err != noErr) goto exit;
- err = FindHeaderHandle(text, "Reply-To", &replyto);
- if (err != noErr) goto exit;
- err = FindHeaderHandle(text, "References", &references);
- if (err != noErr) goto exit;
- err = FindHeaderHandle(text, "Message-ID", &messageid);
- if (err != noErr) goto exit;
- err = FindHeaderHandle(text, "Distribution", &distribution);
- if (err != noErr) goto exit;
-
- err = MakeNewWindow(&wind);
- if (err != noErr) goto exit;
- SetPort(wind);
- info = (TWindow**)GetWRefCon(wind);
-
- if (followupto != nil && MyGetHandleSize(followupto) == 6) {
- followuptoPoster = MyStrNEqual(*followupto, "poster", 6);
- }
-
- if (followuptoPoster) {
- (**info).newsIcon = false;
- (**info).mailIcon = true;
- } else if (reverseIcons) {
- (**info).newsIcon = !gPrefs.replyPost;
- (**info).mailIcon = !gPrefs.replyEmail;
- } else {
- (**info).newsIcon = gPrefs.replyPost;
- (**info).mailIcon = gPrefs.replyEmail;
- }
-
- newsgroupsField = (**info).newsgroupsField;
- if (!followuptoPoster && followupto != nil) {
- MyDisposeHandle((**newsgroupsField).hText);
- (**newsgroupsField).hText = followupto;
- followupto = nil;
- } else if (newsgroups != nil) {
- MyDisposeHandle((**newsgroupsField).hText);
- (**newsgroupsField).hText = newsgroups;
- newsgroups = nil;
- }
- TECalText(newsgroupsField);
- i = 0;
- iEnd = (**newsgroupsField).teLength;
- hText = (**newsgroupsField).hText;
- while (i < iEnd) {
- if (*(*hText+i) == ',' && *(*hText+i+1) != ' ') {
- (**newsgroupsField).selStart = (**newsgroupsField).selEnd = i+1;
- TEKey(' ', newsgroupsField);
- iEnd++;
- i++;
- }
- i++;
- }
-
- toField = (**info).toField;
- if (replyto != nil) {
- MyDisposeHandle((**toField).hText);
- (**toField).hText = replyto;
- replyto = nil;
- } else if (from != nil) {
- MyDisposeHandle((**toField).hText);
- (**toField).hText = from;
- from = nil;
- }
-
- distributionField = (**info).distributionField;
- if (distribution != nil) {
- MyDisposeHandle((**distributionField).hText);
- (**distributionField).hText = distribution;
- distribution = nil;
- }
-
- subjectField = (**info).subjectField;
-
- if (subject != nil) {
- subjectLen = MyGetHandleSize(subject);
- oldReLen = ParseRe(*subject, subjectLen);
- newSubjectLen = subjectLen - oldReLen + 4;
- if (newSubjectLen > subjectLen) {
- err = MySetHandleSize(subject, newSubjectLen);
- if (err != noErr) goto exit;
- }
- BlockMoveData(*subject + oldReLen, *subject + 4, subjectLen - oldReLen);
- if (newSubjectLen < subjectLen) MySetHandleSize(subject, newSubjectLen);
- subjectLen = newSubjectLen;
- BlockMoveData("Re: ", *subject, 4);
- MyDisposeHandle((**subjectField).hText);
- (**subjectField).hText = subject;
- subject = nil;
- } else {
- err = MyTESetText("Re: ", 4, subjectField);
- if (err != noErr) goto exit;
- }
- ChangeSubject(wind);
-
- refLen = references == nil ? 0 : MyGetHandleSize(references);
- idLen = messageid == nil ? 0 : MyGetHandleSize(messageid);
- if (refLen > 0 || idLen > 0) {
- newRefLen = refLen + idLen;
- if (refLen > 0 && idLen > 0) newRefLen++;
- err = MyNewHandle(newRefLen, &newReferences);
- if (err != noErr) goto exit;
- if (refLen > 0) {
- BlockMoveData(*references, *newReferences, refLen);
- if (idLen > 0) {
- *(*newReferences + refLen) = ' ';
- BlockMoveData(*messageid, *newReferences + refLen + 1, idLen);
- }
- } else {
- BlockMoveData(*messageid, *newReferences, idLen);
- }
- err = FoldReferences(newReferences);
- if (err != noErr) goto exit;
- (**info).references = newReferences;
- }
-
- theTE = (**info).theTE;
- err = BuildReplyBody(text, quoteText, start, end,
- messageid, (**toField).hText, (**theTE).hText);
- if (err != noErr) goto exit;
-
- MyDisposeHandle(newsgroups);
- MyDisposeHandle(subject);
- MyDisposeHandle(followupto);
- MyDisposeHandle(from);
- MyDisposeHandle(replyto);
- MyDisposeHandle(references);
- MyDisposeHandle(messageid);
- MyDisposeHandle(distribution);
-
- InitFieldInfo(wind);
- err = DoZoom(wind, inZoomOut);
- if (err != noErr) goto exit;
-
- (**info).isFollowup = true;
-
- MyShowWindow(wind);
- SetPort(port);
- return noErr;
-
- exit:
-
- MyDisposeHandle(newsgroups);
- MyDisposeHandle(subject);
- MyDisposeHandle(followupto);
- MyDisposeHandle(from);
- MyDisposeHandle(replyto);
- MyDisposeHandle(references);
- MyDisposeHandle(messageid);
- MyDisposeHandle(distribution);
- DoClose(wind);
- SetPort(port);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- BuildForwardBody
-
- Build the body of a forward message.
-
- Entry: text = handle to full article text.
- quoteText = handle to text to be quoted, or nil to quote the
- full text.
- start = offset in quoteText of beginning of text to
- be quoted.
- end = offset in quoteText of end of text to be quoted.
- body = handle.
-
- Exit: function result = error code.
- body = handle to message body.
- ----------------------------------------------------------------------------*/
-
- static OSErr BuildForwardBody (Handle text, Handle quoteText, long start,
- long end, Handle body)
- {
- long len, headerLen;
- OSErr err = noErr;
-
- headerLen = FindBody(text);
-
- if (quoteText == nil) {
- len = MyGetHandleSize(text);
- } else {
- len = headerLen + end - start;
- }
-
- err = MySetHandleSize(body, len);
- if (err != noErr) return err;
-
- if (quoteText == nil) {
- BlockMoveData(*text, *body, len);
- } else {
- BlockMoveData(*text, *body, headerLen);
- BlockMoveData(*quoteText + start, *body + headerLen, end - start);
- }
-
- err = QuoteText(body, 0, len);
- if (err != noErr) return err;
-
- len = MyGetHandleSize(body);
- if (len > 0x7fff) {
- MySetHandleSize(body, 0x7fff);
- ErrorMessageNumber(kStrTrunc);
- }
-
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- OpenForwardWindow
-
- Open a forward window.
-
- Entry: text = handle to full article text.
- quoteText = handle to text to be quoted, or nil to quote the
- full text.
- start = offset in quoteText of beginning of text to
- be quoted.
- end = offset in quoteText of end of text to be quoted.
- mailToSelf = true to mail the forwarded message to self.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr OpenForwardWindow (Handle text, Handle quoteText, long start, long end,
- Boolean mailToSelf)
- {
- WindowPtr wind = nil;
- TWindow **info;
- Handle subject = nil;
- OSErr err = noErr;
- TEHandle subjectField, theTE;
- GrafPtr port;
-
- GetPort(&port);
-
- err = MakeNewWindow(&wind);
- if (err != noErr) return err;
- SetPort(wind);
- info = (TWindow**)GetWRefCon(wind);
-
- (**info).newsIcon = false;
- if (mailToSelf) {
- (**info).selfIcon = true;
- } else {
- (**info).mailIcon = true;
- }
-
- err = FindHeaderHandle(text, "Subject", &subject);
- if (err != noErr) goto exit;
- subjectField = (**info).subjectField;
- if (subject != nil) {
- MyDisposeHandle((**subjectField).hText);
- (**subjectField).hText = subject;
- subject = nil;
- ChangeSubject(wind);
- }
-
- theTE = (**info).theTE;
- err = BuildForwardBody(text, quoteText, start, end, (**theTE).hText);
- if (err != noErr) goto exit;
-
- InitFieldInfo(wind);
- err = DoZoom(wind, inZoomOut);
- if (err != noErr) goto exit;
-
- MyShowWindow(wind);
-
- if (mailToSelf) {
- err = SendMessageAndCloseWindow(wind);
- if (err != noErr) goto exit;
- }
-
- SetPort(port);
- return noErr;
-
- exit:
-
- MyDisposeHandle(subject);
- DoClose(wind);
- SetPort(port);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- BuildRedirectBody
-
- Build the body of a redirect message.
-
- Entry: text = handle to full article text.
- quoteText = handle to text to be quoted, or nil to quote the
- full text.
- start = offset in quoteText of beginning of text to
- be quoted.
- end = offset in quoteText of end of text to be quoted.
- body = handle.
-
- Exit: function result = error code.
- body = handle to message body.
- ----------------------------------------------------------------------------*/
-
- static OSErr BuildRedirectBody (Handle text, Handle quoteText, long start,
- long end, Handle body)
- {
- long len, headerLen;
- OSErr err = noErr;
-
- headerLen = FindBody(text);
-
- if (quoteText == nil) {
- len = MyGetHandleSize(text) - headerLen;
- } else {
- len = end - start;
- }
-
- err = MySetHandleSize(body, len);
- if (err != noErr) return err;
-
- if (quoteText == nil) {
- BlockMoveData(*text + headerLen, *body, len);
- } else {
- BlockMoveData(*quoteText + start, *body, len);
- }
-
- if (len > 0x7fff) {
- MySetHandleSize(body, 0x7fff);
- ErrorMessageNumber(kStrTrunc);
- }
-
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- OpenRedirectWindow
-
- Open a redirect window.
-
- Entry: text = handle to full article text.
- quoteText = handle to text to be quoted, or nil to quote the
- full text.
- start = offset in quoteText of beginning of text to
- be quoted.
- end = offset in quoteText of end of text to be quoted.
- mailToSelf = true to mail the redirected message to self.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr OpenRedirectWindow (Handle text, Handle quoteText, long start, long end,
- Boolean mailToSelf)
- {
- WindowPtr wind = nil;
- TWindow **info;
- Handle posterFrom = nil;
- char myFrom[514];
- CStr255 byWayOfFmt;
- char byWayOf[800];
- OSErr err = noErr;
- TEHandle theTE;
- long posterFromLen, byWayOfLen;
- long headerLen;
- Handle extraMail = nil;
- char *p;
- TEHandle extraMailField;
- Handle hText;
- short teLength;
- GrafPtr port;
-
- GetPort(&port);
-
- err = MakeNewWindow(&wind);
- if (err != noErr) goto exit;
- SetPort(wind);
- info = (TWindow**)GetWRefCon(wind);
-
- (**info).newsIcon = false;
- if (mailToSelf) {
- (**info).selfIcon = true;
- } else {
- (**info).mailIcon = true;
- }
-
- headerLen = FindBody(text);
- for (p = *text + headerLen - 1; p >= *text && *p == CR; p--) /* do nothing */;
- p++;
- headerLen = p - *text;
- err = MyNewHandle(headerLen, &extraMail);
- if (err != noErr) goto exit;
- BlockMoveData(*text, *extraMail, headerLen);
-
- err = FindHeaderHandle(extraMail, "From", &posterFrom);
- if (err != noErr) goto exit;
-
- err = MoveHeaderLine(extraMail, "Subject", (**info).subjectField);
- if (err != noErr) goto exit;
- err = MoveHeaderLine(extraMail, "Reply-To", (**info).replytoField);
- if (err != noErr) goto exit;
- err = MoveHeaderLine(extraMail, "Keywords", (**info).keywordsField);
- if (err != noErr) goto exit;
- DeleteHeaderLine(extraMail, "To");
- DeleteHeaderLine(extraMail, "Cc");
- DeleteHeaderLine(extraMail, "Bcc");
- DeleteHeaderLine(extraMail, "From");
-
- ChangeSubject(wind);
-
- if (posterFrom != nil) {
- MakeFromHeader(myFrom);
- posterFromLen = MyGetHandleSize(posterFrom);
- GetCString(kStrByWayOfFmt, byWayOfFmt);
- sprintf(byWayOf, byWayOfFmt, myFrom);
- byWayOfLen = strlen(byWayOf);
- err = MySetHandleSize(posterFrom, posterFromLen + byWayOfLen);
- if (err != noErr) goto exit;
- BlockMoveData(byWayOf, *posterFrom + posterFromLen, byWayOfLen);
- (**info).from = posterFrom;
- posterFrom = nil;
- }
-
- extraMailField = (**info).extraMailField;
- TESetSelect(0x7fff, 0x7fff, extraMailField);
- hText = (**extraMailField).hText;
- teLength = (**extraMailField).teLength;
- if (teLength > 0 && *(*hText + teLength - 1) != CR) TEKey(CR, extraMailField);
- err = MyHandAndHand(extraMail, hText);
- if (err != noErr) goto exit;
- MyDisposeHandle(extraMail);
- extraMail = nil;
-
- TESetSelect(0, 0x7fff, (**info).signatureField);
- TEDelete((**info).signatureField);
-
- theTE = (**info).theTE;
- err = BuildRedirectBody(text, quoteText, start, end, (**theTE).hText);
- if (err != noErr) goto exit;
-
- InitFieldInfo(wind);
- err = DoZoom(wind, inZoomOut);
- if (err != noErr) goto exit;
-
- MyShowWindow(wind);
-
- if (mailToSelf) {
- err = SendMessageAndCloseWindow(wind);
- if (err != noErr) goto exit;
- }
-
- SetPort(port);
- return noErr;
-
- exit:
-
- MyDisposeHandle(posterFrom);
- MyDisposeHandle(extraMail);
- DoClose(wind);
- SetPort(port);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- OpenMailWindow
-
- Open a mail message window.
-
- Entry: address = email address of recipient or emailto URL.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr OpenMailWindow (char *address)
- {
- WindowPtr wind = nil;
- TWindow **info;
- CStr255 addr;
- OSErr err = noErr;
- GrafPtr port;
-
- GetPort(&port);
-
- if (MyStrNEqual(address, "mailto::", 8)) {
- strcpy(addr, address+8);
- } else if (MyStrNEqual(address, "mailto:", 7)) {
- strcpy(addr, address+7);
- } else {
- strcpy(addr, address);
- }
-
- err = MakeNewWindow(&wind);
- if (err != noErr) return err;
- SetPort(wind);
- info = (TWindow**)GetWRefCon(wind);
-
- (**info).newsIcon = false;
- (**info).mailIcon = true;
-
- err = MyTESetText(addr, strlen(addr), (**info).toField);
- if (err != noErr) goto exit;
-
- InitFieldInfo(wind);
- err = DoZoom(wind, inZoomOut);
- if (err != noErr) goto exit;
-
- MyShowWindow(wind);
- SetPort(port);
- return noErr;
-
- exit:
-
- DoClose(wind);
- SetPort(port);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- ReadMessageWindDataFork
-
- Read the data fork of a saved message window.
-
- Entry: wind = pointer to message window.
- fSpec = pointer to file spec.
-
- Exit: function result = error code.
- *truncated = true if body >= 32K and truncated
- ----------------------------------------------------------------------------*/
-
- static OSErr ReadMessageWindDataFork (WindowPtr wind, FSSpec *fSpec,
- Boolean *truncated)
- {
- TWindow **info;
- OSErr err = noErr;
- short fRefNum = 0;
- long length;
- TEHandle theTE;
- Handle hText;
- char state;
-
- *truncated = false;
-
- info = (TWindow**)GetWRefCon(wind);
- theTE = (**info).theTE;
- hText = (**theTE).hText;
-
- err = FSpOpenDF(fSpec, fsRdPerm, &fRefNum);
- if (err != noErr) goto exit;
- err = GetEOF(fRefNum, &length);
- if (err != noErr) goto exit;
- if (length > 0x7fff) {
- length = 0x7fff;
- *truncated = true;
- }
-
- err = MySetHandleSize(hText, length);
- if (err != noErr) goto exit;
-
- state = MyHGetState(hText);
- err = FSRead(fRefNum, &length, *hText);
- MyHSetState(hText, state);
- if (err != noErr) goto exit;
-
- MyFSClose(fRefNum, nil);
- return noErr;
-
- exit:
-
- if (fRefNum != 0) MyFSClose(fRefNum, nil);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- ReadOneHandle
-
- Read one relocatable block from a saved message window resource fork.
-
- Entry: id = resource id.
-
- Exit: function result = error code.
- *theHandle = handle to block, or nil if resource does not exist.
- ----------------------------------------------------------------------------*/
-
- static OSErr ReadOneHandle (short id, Handle *theHandle)
- {
- Handle h = nil;
- OSErr err = noErr;
-
- err = MyGet1Resource('TEXT', id, &h);
- if (err == resNotFound) {
- *theHandle = nil;
- return noErr;
- }
- if (err != noErr) return err;
- MyDetachResource(h);
- *theHandle = h;
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- ReadOneTEField
-
- Read one saved TE field from a saved message window resource fork.
-
- Entry: field = handle to TE field.
- id = resource id.
-
- Exit: function result = error code.
- *truncated = true if field >= 32K and truncated.
- ----------------------------------------------------------------------------*/
-
- static OSErr ReadOneTEField (TEHandle field, short id, Boolean *truncated)
- {
- Handle hText;
- long len;
- OSErr err = noErr;
-
- *truncated = false;
- err = ReadOneHandle(id, &hText);
- if (err != noErr) return err;
- if (hText == nil) return noErr;
- len = MyGetHandleSize(hText);
- if (len > 0x7fff) {
- len = 0x7fff;
- *truncated = true;
- }
- MyHLock(hText);
- err = MyTESetText(*hText, len, field);
- MyDisposeHandle(hText);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- ReadMessageWindResourceFork
-
- Read the resource fork of a saved message window.
-
- Entry: wind = pointer to message window.
- fSpec = pointer to file spec.
-
- Exit: function result = error code.
- *truncated = true if field >= 32K and truncated.
- *pos = saved window position.
- ----------------------------------------------------------------------------*/
-
- static OSErr ReadMessageWindResourceFork (WindowPtr wind, FSSpec *fSpec,
- Boolean *truncated, TSavedWindPos *pos)
- {
- TWindow **info;
- OSErr err = noErr;
- short refNum = 0;
- TMiscMessageWindowInfo **miscInfo = nil;
- CStr255 tabStopsValueStr;
- Handle theHandle, h;
- Boolean t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13;
-
- *truncated = false;
- pos->valid = false;
-
- info = (TWindow**)GetWRefCon(wind);
-
- err = MyFSpOpenResFile(fSpec, fsRdPerm, &refNum);
- if (err == eofErr || err == fnfErr) return noErr;
- if (err != noErr) goto exit;
-
- err = MyGet1Resource('MISC', 128, &miscInfo);
- if (err == noErr) {
- (**info).newsIcon = (**miscInfo).newsIcon;
- (**info).mailIcon = (**miscInfo).mailIcon;
- (**info).selfIcon = (**miscInfo).selfIcon;
- (**info).tabEnabled = (**miscInfo).tabEnabled;
- (**info).wrapOnSend = (**miscInfo).wrapOnSend;
- (**info).tabStops = (**miscInfo).tabStops;
- MyReleaseResource(miscInfo);
- }
-
- SetControlValue((**info).tabCheckbox, (**info).tabEnabled ? 1 : 0);
- SetControlValue((**info).wrapCheckbox, (**info).wrapOnSend ? 1 : 0);
- sprintf(tabStopsValueStr, "%d", (**info).tabStops);
- err = MyTESetText(tabStopsValueStr, strlen(tabStopsValueStr), (**info).tabField);
- if (err != noErr) goto exit;
-
- err = ReadOneTEField((**info).quoteStringField, kQuoteStringResID, &t1);
- if (err != noErr) goto exit;
- err = ReadOneTEField((**info).newsgroupsField, kNewsgroupsResID, &t2);
- if (err != noErr) goto exit;
- err = ReadOneTEField((**info).toField, kToResID, &t3);
- if (err != noErr) goto exit;
- err = ReadOneTEField((**info).subjectField, kSubjectResID, &t4);
- if (err != noErr) goto exit;
- err = ReadOneTEField((**info).ccField, kCcResID, &t5);
- if (err != noErr) goto exit;
- err = ReadOneTEField((**info).bccField, kBccResID, &t6);
- if (err != noErr) goto exit;
- err = ReadOneTEField((**info).replytoField, kReplytoResID, &t7);
- if (err != noErr) goto exit;
- err = ReadOneTEField((**info).followuptoField, kFollowuptoResID, &t8);
- if (err != noErr) goto exit;
- err = ReadOneTEField((**info).keywordsField, kKeywordsResID, &t9);
- if (err != noErr) goto exit;
- err = ReadOneTEField((**info).distributionField, kDistributionResID, &t10);
- if (err != noErr) goto exit;
- err = ReadOneTEField((**info).extraNewsField, kExtraNewsResID, &t11);
- if (err != noErr) goto exit;
- err = ReadOneTEField((**info).extraMailField, kExtraMailResID, &t12);
- if (err != noErr) goto exit;
- err = ReadOneTEField((**info).signatureField, kSignatureResID, &t13);
- if (err != noErr) goto exit;
-
- *truncated = t1 || t2 || t3 || t4 || t5 || t6 || t7 || t8 ||
- t9 || t10 || t11 || t12 || t13;
-
- err = ReadOneHandle(kReferencesResID, &theHandle);
- if (err != noErr) goto exit;
- (**info).references = theHandle;
-
- err = ReadOneHandle(kFromResID, &theHandle);
- if (err != noErr) goto exit;
- (**info).from = theHandle;
-
- err = MyGet1Resource('WPOS', 128, &h);
- if (err == noErr) {
- if (MyGetHandleSize(h) == sizeof(Point)) {
- pos->valid = true;
- pos->oldFormat = true;
- BlockMoveData(*h, &pos->userState, sizeof(Point));
- } else {
- BlockMoveData(*h, pos, sizeof(TSavedWindPos));
- }
- }
-
- MyCloseResFile(refNum);
- return noErr;
-
- exit:
-
- if (refNum != 0) MyCloseResFile(refNum);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- OpenMessageFile
-
- Open a saved message.
-
- Entry: fSpec = pointer to file spec.
-
- Exit: function result = error code.
- *wind = pointer to opened message window.
- ----------------------------------------------------------------------------*/
-
- OSErr OpenMessageFile (FSSpec *fSpec, WindowPtr *wind)
- {
- OSErr err = noErr;
- WindowPtr w = nil;
- TWindow** info;
- FSSpec windFile;
- GrafPtr port;
- Boolean bodyTruncated, fieldTruncated;
- Boolean wasChanged;
- AliasHandle alias;
- TWindowKind kind;
- TSavedWindPos pos;
- Boolean needsZooming;
-
- GetPort(&port);
-
- /* Check to see if the file is already open. If it is, bring its
- window to the front. */
-
- for (w = FrontWindow();
- w != nil;
- w = (WindowPtr)((WindowPeek)w)->nextWindow)
- {
- kind = GetMyWindowKind(w);
- if (kind == kMessage) {
- info = (TWindow**)GetWRefCon(w);
- if ((**info).alias != nil) {
- err = ResolveAlias(nil, (**info).alias, &windFile, &wasChanged);
- if (err == noErr && IsEqualFSSpec(&windFile, fSpec)) {
- MySelectWindow(w);
- *wind = w;
- return noErr;
- }
- }
- }
- }
-
- /* Make a new message window and read it from the file. */
-
- err = MakeNewWindow(&w);
- if (err != noErr) goto exit;
- SetPort(w);
-
- err = ReadMessageWindDataFork(w, fSpec, &bodyTruncated);
- if (err != noErr) goto exit;
-
- err = ReadMessageWindResourceFork(w, fSpec, &fieldTruncated, &pos);
- if (err != noErr) goto exit;
-
- info = (TWindow**)GetWRefCon(w);
- (**info).changed = false;
-
- SetWTitle(w, fSpec->name);
-
- err = NewAlias(nil, fSpec, &alias);
- if (err != noErr) goto exit;
- (**info).alias = alias;
-
- InitFieldInfo(w);
-
- RestoreWindPos(w, &pos, &needsZooming);
- ResizeContents(w);
- if (needsZooming) {
- err = DoZoom(w, inZoomOut);
- if (err != noErr) goto exit;
- }
- (**info).movedSinceLastSave = false;
-
- MyShowWindow(w);
-
- SetPort(port);
-
- if (bodyTruncated) CautionMessageNumber(kStrMessageBodyTruncated);
- if (fieldTruncated) CautionMessageNumber(kStrMessageFieldTruncated);
-
- *wind = w;
- return noErr;
-
- exit:
-
- DoClose(w);
- SetPort(port);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- FormFileName
-
- Form the default file name for saving a message.
-
- Entry: wind = pointer to message window.
-
- Exit: fileName = default file name.
- ----------------------------------------------------------------------------*/
-
- static void FormFileName (WindowPtr wind, Str31 fileName)
- {
- Str255 title;
-
- ChangeSubject(wind);
- GetWTitle(wind, title);
- MakeLegalFileName(title, fileName);
- }
-
-
-
- /*----------------------------------------------------------------------------
- PresentStandardMessageSaveFileDialog
-
- Present the standard save file dialog.
-
- Entry: fileName = default file name.
-
- Exit: function result = error code.
- *fSpec = file spec.
- *scriptTag = script code.
- ----------------------------------------------------------------------------*/
-
- static OSErr PresentStandardMessageSaveFileDialog (Str31 fileName, FSSpec *fSpec,
- ScriptCode *scriptTag)
- {
- StandardFileReply reply;
- Str255 prompt;
-
- GetPString(kStrSaveMessagePrompt, prompt);
- MyStandardPutFile(prompt, fileName, &reply,
- gPrefs.savedMsgDefaultFolder ? gPrefs.savedMsgDefaultFolderAlias : nil);
- if (!reply.sfGood) return userCanceledErr;
- *fSpec = reply.sfFile;
- *scriptTag = reply.sfScript;
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- CheckMessageFileExists
-
- Check to see if a message file already exists in the default message
- file save directory. If it does, present an alert asking the user to
- replace, cancel, or pick a new name.
-
- Entry: fileName = file name.
-
- Exit: function result = error code.
- *fSpec = file spec.
- *scriptTag = script code.
- ----------------------------------------------------------------------------*/
-
- static OSErr CheckMessageFileExists (Str31 fileName, FSSpec *fSpec, ScriptCode *scriptTag)
- {
- OSErr err = noErr;
- DialogPtr dlg = nil;
- Boolean valid;
- short item;
-
- ValidateSavedFolderAlias(gPrefs.savedMsgDefaultFolderAlias, &fSpec->vRefNum,
- &fSpec->parID, &valid);
- if (!valid) {
- ErrorMessageNumber(kStrDefaultMsgFoldNotFound);
- err = PresentStandardMessageSaveFileDialog(fileName, fSpec, scriptTag);
- if (err != noErr) return err;
- return noErr;
- }
- *scriptTag = smSystemScript;
- CopyPascalString(fSpec->name, fileName);
- err = FileOrFolderExists(fSpec);
- if (err == fnfErr) return noErr;
- if (err != noErr) return err;
-
- err = MyGetNewDialog(kMessageFileExistsAlert, 1, 2, &dlg);
- if (err != noErr) return err;
- ParamText(fileName, "\p", "\p", "\p");
- SetItemKeyEquivalent(dlg, 3, 'R');
- SysBeep(0);
- MyModalDialog(dlg, gDialogFilterUPP, &item);
- err = DoClose(dlg);
- if (err != noErr) return err;
- switch (item) {
- case 1: /* Pick a New Name */
- err = PresentStandardMessageSaveFileDialog(fileName, fSpec, scriptTag);
- if (err != noErr) return err;
- return noErr;
- case 2: /* Cancel */
- return userCanceledErr;
- case 3: /* Replace */
- return noErr;
- }
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- SaveMessageWindDataFork
-
- Save a message window data fork.
-
- Entry: wind = pointer to message window.
- fSpec = pointer to file spec.
- scriptTag = script code.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr SaveMessageWindDataFork (WindowPtr wind, FSSpec *fSpec, ScriptCode scriptTag)
- {
- TWindow **info;
- TEHandle theTE;
- Handle text;
- OSErr err = noErr;
- long length;
- short refNum = 0;
- char state;
- Boolean empty;
-
- info = (TWindow**)GetWRefCon(wind);
- theTE = (**info).theTE;
- text = (**theTE).hText;
-
- state = MyHGetState(text);
-
- err = OpenDataForkWriteCreateIfMissing(fSpec, kNewsWatcherSignature,
- kSavedMessageFileType, scriptTag, false, &refNum, &empty);
- if (err != noErr) goto exit;
-
- length = MyGetHandleSize(text);
- MyHLock(text);
- err = MyFSWriteNoCache(refNum, &length, *text, nil);
- if (err != noErr) goto exit;
- MyHSetState(text, state);
- MyFSClose(refNum, nil);
- return noErr;
-
- exit:
-
- MyHSetState(text, state);
- if (refNum != 0) MyFSClose(refNum, nil);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- SaveOneHandle
-
- Save one relocatable block on a message window resource fork.
-
- Entry: theHandle = handle to block to be saved.
- id = resource id.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr SaveOneHandle (Handle theHandle, short id)
- {
- OSErr err = noErr;
-
- if (theHandle == nil) return noErr;
- err = MyReplaceResource(theHandle, 'TEXT', id, "\p");
- if (err != noErr) return err;
- WriteResource(theHandle);
- DetachResource(theHandle);
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- SaveOneTEField
-
- Save one TE field on a message window resource fork.
-
- Entry: field = handle to TE field.
- id = resource id.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr SaveOneTEField (TEHandle field, short id)
- {
- return SaveOneHandle((**field).hText, id);
- }
-
-
-
- /*----------------------------------------------------------------------------
- SaveMessageWindResourceFork
-
- Save a message window resource fork.
-
- Entry: wind = pointer to message window.
- fSpec = pointer to file spec.
- scriptTag = script code.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr SaveMessageWindResourceFork (WindowPtr wind, FSSpec *fSpec,
- ScriptCode scriptTag)
- {
- TWindow **info;
- short refNum = 0;
- OSErr err = noErr;
- TMiscMessageWindowInfo **miscInfo = nil;
-
- info = (TWindow**)GetWRefCon(wind);
-
- err = OpenResFileWriteCreateIfMissing(fSpec, kNewsWatcherSignature,
- kSavedMessageFileType, scriptTag, &refNum);
- if (err != noErr) goto exit;
-
- err = MyNewHandle(sizeof(TMiscMessageWindowInfo), &miscInfo);
- if (err != noErr) goto exit;
- (**miscInfo).newsIcon = (**info).newsIcon;
- (**miscInfo).mailIcon = (**info).mailIcon;
- (**miscInfo).selfIcon = (**info).selfIcon;
- (**miscInfo).tabEnabled = (**info).tabEnabled;
- (**miscInfo).wrapOnSend = (**info).wrapOnSend;
- (**miscInfo).tabStops = (**info).tabStops;
- err = MyReplaceResource(miscInfo, 'MISC', 128, "\p");
- if (err != noErr) goto exit;
- miscInfo = nil;
-
- err = SaveOneTEField((**info).quoteStringField, kQuoteStringResID);
- if (err != noErr) goto exit;
- err = SaveOneTEField((**info).newsgroupsField, kNewsgroupsResID);
- if (err != noErr) goto exit;
- err = SaveOneTEField((**info).toField, kToResID);
- if (err != noErr) goto exit;
- err = SaveOneTEField((**info).subjectField, kSubjectResID);
- if (err != noErr) goto exit;
- err = SaveOneTEField((**info).ccField, kCcResID);
- if (err != noErr) goto exit;
- err = SaveOneTEField((**info).bccField, kBccResID);
- if (err != noErr) goto exit;
- err = SaveOneTEField((**info).replytoField, kReplytoResID);
- if (err != noErr) goto exit;
- err = SaveOneTEField((**info).followuptoField, kFollowuptoResID);
- if (err != noErr) goto exit;
- err = SaveOneTEField((**info).keywordsField, kKeywordsResID);
- if (err != noErr) goto exit;
- err = SaveOneTEField((**info).distributionField, kDistributionResID);
- if (err != noErr) goto exit;
- err = SaveOneTEField((**info).extraNewsField, kExtraNewsResID);
- if (err != noErr) goto exit;
- err = SaveOneTEField((**info).extraMailField, kExtraMailResID);
- if (err != noErr) goto exit;
- err = SaveOneTEField((**info).signatureField, kSignatureResID);
- if (err != noErr) goto exit;
-
- err = SaveOneHandle((**info).references, kReferencesResID);
- if (err != noErr) goto exit;
- err = SaveOneHandle((**info).from, kFromResID);
- if (err != noErr) goto exit;
-
- err = WriteProgramNameResource(kStrNewsWatcher);
- if (err != noErr) goto exit;
-
- err = SaveWindPosAsResource(wind);
- if (err != noErr) goto exit;
-
- MyCloseResFile(refNum);
-
- return noErr;
-
- exit:
-
- if (refNum != 0) MyCloseResFile(refNum);
- MyDisposeHandle(miscInfo);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- SaveMessageWindToFile
-
- Save a message window to a file.
-
- Entry: wind = pointer to message window.
- fSpec = pointer to file spec.
- scriptTag = script code.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr SaveMessageWindToFile (WindowPtr wind, FSSpec *fSpec, ScriptCode scriptTag)
- {
- TWindow **info;
- OSErr err = noErr;
- Boolean savedCriticalSeq;
- AliasHandle alias;
-
- BeginCriticalMemorySequence(&savedCriticalSeq);
-
- info = (TWindow**)GetWRefCon(wind);
-
- err = SaveMessageWindDataFork(wind, fSpec, scriptTag);
- if (err != noErr) goto exit;
-
- err = SaveMessageWindResourceFork(wind, fSpec, scriptTag);
- if (err != noErr) goto exit;
-
- err = NewAlias(nil, fSpec, &alias);
- if (err != noErr) goto exit;
- MyDisposeHandle((**info).alias);
- (**info).alias = alias;
- (**info).changed = false;
-
- EndCriticalMemorySequence(savedCriticalSeq);
-
- return noErr;
-
- exit:
-
- EndCriticalMemorySequence(savedCriticalSeq);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- MakeNewTestMessageWindow
-
- Create a new message window for testing (development version only).
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- #ifdef kDevelopmentVersion
-
- OSErr MakeNewTestMessageWindow (void)
- {
- WindowPtr wind;
- OSErr err = noErr;
- GrafPtr port;
-
- GetPort(&port);
-
- err = MakeNewWindow(&wind);
- if (err != noErr) return err;
- SetPort(wind);
- InitFieldInfo(wind);
- err = DoZoom(wind, inZoomOut);
- if (err != noErr) goto exit;
- MyShowWindow(wind);
- SetPort(port);
- return noErr;
-
- exit:
-
- DoClose(wind);
- SetPort(port);
- return err;
- }
-
- #endif
-
-
-
- /*----------------------------------------------------------------------------
- Find
-
- Search a message window for a pattern.
-
- Entry: wind = pointer to text window.
- offset = offset into text to begin search.
- gFindPattern = pattern.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr Find (WindowPtr wind, short offset)
- {
- TWindow **info;
- short curField;
- TMsgFieldInfo **fields;
- TEHandle edit;
- Handle hText;
- short len;
- char state;
- long matchOffset;
- OSErr err = noErr;
-
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- fields = (**info).fields;
- edit = (*fields)[curField].edit;
- hText = (**edit).hText;
- len = (**edit).teLength - offset;
- state = MyHGetState(hText);
- MyHLock(hText);
- err = MyNSubstringSearch(*hText+offset, gFindPattern, len, &matchOffset,
- GiveTime);
- MyHSetState(hText, state);
- if (err != noErr) return err;
- if (matchOffset == -1) {
- SysBeep(0);
- } else {
- offset += matchOffset;
- TESetSelect(offset, offset + strlen(gFindPattern), edit);
- ScrollToMiddle(wind, offset);
- }
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoNewMessage
-
- Handle the "New Message" command.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr DoNewMessage (void)
- {
- WindowPtr wind;
- TWindow **info;
- OSErr err = noErr;
- GrafPtr port;
-
- GetPort(&port);
-
- err = MakeNewWindow(&wind);
- if (err != noErr) return err;
- SetPort(wind);
- info = (TWindow**)GetWRefCon(wind);
-
- (**info).newsIcon = true;
- (**info).mailIcon = false;
-
- err = InitializeGroupList(MyFrontWindow(), (**info).newsgroupsField);
- if (err != noErr) goto exit;
-
- InitFieldInfo(wind);
- err = DoZoom(wind, inZoomOut);
- if (err != noErr) goto exit;
-
- MyShowWindow(wind);
- SetPort(port);
- return noErr;
-
- exit:
-
- DoClose(wind);
- SetPort(port);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoSave
-
- Handle the "Save" command.
-
- Entry: wind = pointer to message window.
- modifiers = modifiers field from event record.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoSave (WindowPtr wind, short modifiers)
- {
- TWindow **info;
- Str31 fileName;
- FSSpec fSpec;
- ScriptCode scriptTag;
- OSErr err = noErr;
- AliasHandle alias;
- Boolean wasChanged;
-
- info = (TWindow**)GetWRefCon(wind);
- alias = (**info).alias;
- if (alias != nil) {
- err = ResolveAlias(nil, alias, &fSpec, &wasChanged);
- if (err != noErr) alias = nil;
- scriptTag = smSystemScript;
- }
- if (alias == nil) {
- FormFileName(wind, fileName);
- if (gPrefs.savedMsgDefaultFolder && (modifiers & optionKey) == 0) {
- err = CheckMessageFileExists(fileName, &fSpec, &scriptTag);
- if (err != noErr) return err;
- } else {
- err = PresentStandardMessageSaveFileDialog(fileName, &fSpec, &scriptTag);
- if (err != noErr) return err;
- }
- }
- return SaveMessageWindToFile(wind, &fSpec, scriptTag);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoSaveAs
-
- Handle the "Save As" command.
-
- Entry: wind = pointer to message window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoSaveAs (WindowPtr wind)
- {
- Str31 fileName;
- FSSpec fSpec;
- ScriptCode scriptTag;
- OSErr err = noErr;
-
- FormFileName(wind, fileName);
- err = PresentStandardMessageSaveFileDialog(fileName, &fSpec, &scriptTag);
- if (err != noErr) return err;
- return SaveMessageWindToFile(wind, &fSpec, scriptTag);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoPrint
-
- Handle the "Print" command.
-
- Entry: wind = pointer to article window.
- modifiers = modifiers field from event record.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoPrint (WindowPtr wind, short modifiers)
- {
- TWindow **info;
- TEHandle theTE;
- Handle text;
- OSErr err = noErr;
- CStr255 title;
- long start, end;
-
- err = StartPrint();
- if (err != noErr) return err;
-
- err = DisplayStatusMessageNumber(kStrPrinting);
- if (err != noErr) return err;
-
- GetWTitle(wind, (StringPtr)title);
- p2cstr((StringPtr)title);
-
- info = (TWindow**)GetWRefCon(wind);
- theTE = (**info).theTE;
- start = (**theTE).selStart;
- end = (**theTE).selEnd;
-
- if ((modifiers & shiftKey) == 0 || start >= end) {
- err = BuildMessageForPrinting(wind, &text);
- if (err != noErr) return err;
- start = 0;
- end = MyGetHandleSize(text);
- err = PrintText(text, start, end, title);
- MyDisposeHandle(text);
- return err;
- } else {
- text = (**theTE).hText;
- return PrintText(text, start, end, title);
- }
-
- if ((modifiers & shiftKey) == 0 || start >= end) {
- start = 0;
- end = MyGetHandleSize(text);
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoCut
-
- Handle the "Cut" command.
-
- Entry: wind = pointer to active message window.
- ----------------------------------------------------------------------------*/
-
- static void DoCut (WindowPtr wind)
- {
- TWindow **info;
- short curField;
- TMsgFieldInfo **fields;
- TEHandle edit;
-
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- fields = (**info).fields;
- edit = (*fields)[curField].edit;
- MyTECut(edit);
- AdjustCurFieldHeight(wind);
- (**info).changed = true;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoCopy
-
- Handle the "Copy" command.
-
- Entry: wind = pointer to active message window.
- ----------------------------------------------------------------------------*/
-
- static void DoCopy (WindowPtr wind)
- {
- TWindow **info;
- short curField;
- TMsgFieldInfo **fields;
- TEHandle edit;
-
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- fields = (**info).fields;
- edit = (*fields)[curField].edit;
- MyTECopy(edit);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoPaste
-
- Handle the "Paste" and "Paste as Quotation" commands.
-
- Entry: wind = pointer to active message window.
- quote = true if "Paste as Quotation".
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoPaste (WindowPtr wind, Boolean quote)
- {
- TWindow **info;
- short curField;
- TMsgFieldInfo **fields;
- TEHandle edit;
- long scrapOffset;
- OSErr err = noErr;
-
- gDragData = nil;
-
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- if (curField < (**info).firstScrollingField && quote) return noErr;
- fields = (**info).fields;
- edit = (*fields)[curField].edit;
-
- if (!quote && GetScrap(nil, kNewsWatcherSignature, &scrapOffset) > 0 &&
- (edit == (**info).newsgroupsField || edit == (**info).followuptoField))
- {
-
- err = MyNewHandle(0, &gDragData);
- if (err != noErr) goto exit;
- GetScrap(gDragData, kNewsWatcherSignature, &scrapOffset);
- gDragDestWindow = wind;
- gFinalDestField = edit;
- err = HandleGroupDragReceivePostProcessor();
- if (err != noErr) goto exit;
- MyDisposeHandle(gDragData);
- gDragData = nil;
-
- } else {
-
- err = InsertText(wind, TEScrapHandle(), MyTEGetScrapLen(), edit,
- (**edit).selStart, true, quote, true);
- if (err != noErr) goto exit;
- }
-
- return noErr;
-
- exit:
-
- MyDisposeHandle(gDragData);
- gDragData = nil;
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoClear
-
- Handle the "Clear" command.
-
- Entry: wind = pointer to active message window.
- ----------------------------------------------------------------------------*/
-
- static void DoClear (WindowPtr wind)
- {
- TWindow **info;
- short curField;
- TMsgFieldInfo **fields;
- TEHandle edit;
- Boolean extraSpaceDeleted;
-
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- fields = (**info).fields;
- edit = (*fields)[curField].edit;
- MyTEDelete(edit, false, &extraSpaceDeleted);
- AdjustCurFieldHeight(wind);
- (**info).changed = true;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoSelectAll
-
- Handle the "Select All" command.
-
- Entry: wind = pointer to active message window.
- ----------------------------------------------------------------------------*/
-
- static void DoSelectAll (WindowPtr wind)
- {
- TWindow **info;
- short curField;
- TMsgFieldInfo **fields;
- TEHandle edit;
-
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- fields = (**info).fields;
- edit = (*fields)[curField].edit;
- TESetSelect(0, 0x7fff, edit);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoFind
-
- Handle the "Find" command for a message window.
-
- Entry: wind = pointer to message window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoFind (WindowPtr wind)
- {
- TWindow **info;
- OSErr err = noErr;
- short curField;
- TMsgFieldInfo **fields;
- TEHandle edit;
-
- err = DoFindDialog();
- if (err != noErr) return err;
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- fields = (**info).fields;
- edit = (*fields)[curField].edit;
- return Find(wind, gPrefs.startFindAtBeginning ? 0 : (**edit).selStart);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoFindAgain
-
- Handle the "Find Again" command for a message window.
-
- Entry: wind = pointer to message window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoFindAgain (WindowPtr wind)
- {
- TWindow **info;
- short curField;
- TMsgFieldInfo **fields;
- TEHandle edit;
-
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- fields = (**info).fields;
- edit = (*fields)[curField].edit;
- return Find(wind, (**edit).selEnd);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoEnterSelection
-
- Handle the "Enter Selection" command for a message window.
-
- Entry: wind = pointer to message window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoEnterSelection (WindowPtr wind)
- {
- TWindow **info;
- short curField;
- TMsgFieldInfo **fields;
- TEHandle edit;
- short selStart, selEnd, len;
- Handle hText;
-
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- fields = (**info).fields;
- edit = (*fields)[curField].edit;
- selStart = (**edit).selStart;
- selEnd = (**edit).selEnd;
- hText = (**edit).hText;
- if (selStart >= selEnd || selEnd > selStart + 255) return noErr;
- len = selEnd - selStart;
- BlockMoveData(*hText + selStart, gFindPattern, len);
- gFindPattern[len] = 0;
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoShowHideDetails
-
- Handle the "Show/Hide Details" command.
-
- Entry: wind = pointer to active message window.
- ----------------------------------------------------------------------------*/
-
- static void DoShowHideDetails (WindowPtr wind)
- {
- TWindow **info;
- Boolean showDetails;
- short iconPanelHeight, panelHeight, width, height;
- ControlHandle vScroll, tabCheckbox, wrapCheckbox;
- Rect r;
-
- info = (TWindow**)GetWRefCon(wind);
- showDetails = !(**info).showDetails;
- (**info).showDetails = showDetails;
- iconPanelHeight = panelHeight = (**info).iconPanelHeight;
- if (showDetails) panelHeight += (**info).optionsPanelHeight;
- (**info).panelHeight = panelHeight;
- r = wind->portRect;
- width = r.right;
- height = r.bottom;
- r.top = iconPanelHeight;
- r.bottom -= 15;
- EraseRect(&r);
- InvalRect(&r);
- vScroll = (**info).vScroll;
- SetRect(&r, width-15, panelHeight-1, width+1, height-14);
- (**vScroll).contrlRect = r;
- tabCheckbox = (**info).tabCheckbox;
- wrapCheckbox = (**info).wrapCheckbox;
- (**tabCheckbox).contrlVis = showDetails;
- (**wrapCheckbox).contrlVis = showDetails;
- ChangeDisplayedFields(wind);
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoRot13
-
- Handle the "Rot13" command.
-
- Entry: wind = pointer to active message window.
- ----------------------------------------------------------------------------*/
-
- static void DoRot13 (WindowPtr wind)
- {
- TWindow **info;
- short curField;
- TMsgFieldInfo **fields;
- TEHandle edit;
- Rect r;
-
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- if (curField < (**info).firstScrollingField) return;
- fields = (**info).fields;
- edit = (*fields)[curField].edit;
- Rot13Text((**edit).hText, (**edit).selStart, (**edit).selEnd);
- r = (**edit).viewRect;
- InvalRect(&r);
- (**info).changed = true;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoInsertSpoilerCharacter
-
- Handle the "Insert Spoiler Character" command.
-
- Entry: wind = pointer to active message window.
- ----------------------------------------------------------------------------*/
-
- static void DoInsertSpoilerCharacter (WindowPtr wind)
- {
- TWindow **info;
- short curField;
- TMsgFieldInfo **fields;
- TEHandle edit;
-
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- fields = (**info).fields;
- edit = (*fields)[curField].edit;
- if (edit != (**info).theTE) {
- SysBeep(0);
- return;
- }
- if ((long)(**edit).teLength - (long)(**edit).selEnd +
- (long)(**edit).selStart + 1 > 0x7fff) goto exit;
- TEKey(FF, edit);
- AdjustCurFieldHeight(wind);
- (**info).changed = true;
- return;
-
- exit:
-
- ErrorMessageNumber(kStrNoMoreChars);
- return;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoWrap
-
- Handle the "Wrap" command.
-
- Entry: wind = pointer to active message window.
- ----------------------------------------------------------------------------*/
-
- static void DoWrap (WindowPtr wind)
- {
- TWindow **info;
- short curField;
- TMsgFieldInfo **fields;
- TEHandle edit;
- Rect r;
-
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- if (curField < (**info).firstScrollingField) return;
- fields = (**info).fields;
- edit = (*fields)[curField].edit;
- Wrap((**edit).hText, (**edit).selStart, (**edit).selEnd);
- TECalText(edit);
- r = (**edit).viewRect;
- InvalRect(&r);
- AdjustCurFieldHeight(wind);
- (**info).changed = true;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoUnwrap
-
- Handle the "Unwrap" command.
-
- Entry: wind = pointer to active message window.
- ----------------------------------------------------------------------------*/
-
- static void DoUnwrap (WindowPtr wind)
- {
- TWindow **info;
- short curField;
- TMsgFieldInfo **fields;
- TEHandle edit;
- Rect r;
-
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- if (curField < (**info).firstScrollingField) return;
- fields = (**info).fields;
- edit = (*fields)[curField].edit;
- UnWrap((**edit).hText, (**edit).selStart, (**edit).selEnd);
- TECalText(edit);
- r = (**edit).viewRect;
- InvalRect(&r);
- AdjustCurFieldHeight(wind);
- (**info).changed = true;
- return;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DoSendMessage
-
- Handles the "Send Message" command.
-
- Entry: wind = pointer to message window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DoSendMessage (WindowPtr wind)
- {
- TWindow **info;
- ControlHandle sendButton;
- long myticks;
-
- info = (TWindow**)GetWRefCon(wind);
- sendButton = (**info).sendButton;
- HiliteControl(sendButton, 1);
- Delay(8, &myticks);
- HiliteControl(sendButton, 0);
- return SendMessageAndCloseWindow(wind);
- }
-
-
-
- /*----------------------------------------------------------------------------
- Activate
-
- Handle an activate event for a message window.
-
- Entry: wind = pointer to message window.
- act = true to activate, false to deactivate.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static void Activate (WindowPtr wind, Boolean act)
- {
- TWindow **info;
- TMsgFieldInfo **fields;
- short curField;
- TEHandle edit;
- Rect r;
-
- info = (TWindow**)GetWRefCon(wind);
- curField = (**info).curField;
- fields = (**info).fields;
- edit = (*fields)[curField].edit;
- if (act) {
- ShowControl((**info).vScroll);
- MyTEActivate(edit);
- } else {
- HideControl((**info).vScroll);
- TEDeactivate(edit);
- }
- r = wind->portRect;
- r.top = r.bottom - 15;
- r.left = r.right - 15;
- InvalRect(&r);
- HandleUpdate(wind);
- }
-
-
-
- /*----------------------------------------------------------------------------
- Update
-
- Handle an update event for a message window.
-
- Entry: wind = pointer to message window.
- ----------------------------------------------------------------------------*/
-
- static void Update (WindowPtr wind)
- {
- TWindow **info;
- short panelHeight, windWidth;
- Rect r, textRect;
- TMsgFieldInfo **fields, *f;
- short numFields, i;
- short updateTop, updateBottom, lineHeight;
- short v;
- TEHandle edit;
- FontInfo fInfo;
- short labelWidth;
- Str255 tabStopsStr, quoteStr;
- char state;
- Boolean showLabels;
-
- info = (TWindow**)GetWRefCon(wind);
- panelHeight = (**info).panelHeight;
- GetFontInfo(&fInfo);
-
- r = wind->portRect;
- r.top += panelHeight;
- ClipRect(&r);
- DrawGrowIcon(wind);
- ClipRect(&wind->portRect);
-
- UpdateControls(wind, wind->visRgn);
-
- showLabels = (**info).showLabels;
- DrawIcon(kNewsIconH, kNewsIconID, (**info).newsIcon, showLabels, kStrNewsIconLabel);
- DrawIcon(kMailIconH, kMailIconID, (**info).mailIcon, showLabels, kStrMailIconLabel);
- DrawIcon(kSelfIconH, kSelfIconID, (**info).selfIcon, showLabels, kStrSelfIconLabel);
-
- windWidth = wind->portRect.right;
- v = (**info).iconPanelHeight - 3;
- MoveTo(0, v);
- LineTo(windWidth, v);
- v += 2;
- MoveTo(0, v);
- LineTo(windWidth, v);
-
- if ((**info).showDetails) {
-
- GetPString(kStrTabStops, tabStopsStr);
- edit = (**info).tabField;
- r = (**edit).viewRect;
- InsetRect(&r, -3, -3);
- FrameRect(&r);
- r = (**edit).viewRect;
- r.right = r.left - 3;
- r.left = r.right - StringWidth(tabStopsStr) - 5;
- TETextBox(tabStopsStr+1, *tabStopsStr, &r, teFlushRight);
- TEUpdate(&wind->portRect, edit);
-
- GetPString(kStrQuoteString, quoteStr);
- edit = (**info).quoteStringField;
- r = (**edit).viewRect;
- InsetRect(&r, -3, -3);
- FrameRect(&r);
- r = (**edit).viewRect;
- r.right = r.left - 3;
- r.left = r.right - StringWidth(quoteStr) - 5;
- TETextBox(quoteStr+1, *quoteStr, &r, teFlushRight);
- TEUpdate(&wind->portRect, edit);
-
- v = (**info).iconPanelHeight + (**info).optionsPanelHeight - 3;
- MoveTo(0, v);
- LineTo(windWidth, v);
- v += 2;
- MoveTo(0, v);
- LineTo(windWidth, v);
-
- }
-
- fields = (**info).fields;
- numFields = (**info).numFields;
- updateTop = (**wind->visRgn).rgnBBox.top;
- updateBottom = (**wind->visRgn).rgnBBox.bottom;
- GetTextRect(wind, &textRect);
- GetViewRect(wind, &r);
- state = MyHGetState(fields);
- MyHLock(fields);
- for (i = (**info).firstScrollingField, f = *fields + i; i < numFields; i++, f++) {
- edit = f->edit;
- lineHeight = (**edit).lineHeight;
- if (f->bottom < updateTop || f->top > updateBottom) continue;
- v = f->top;
- if (f->sepLine) {
- if (v >= textRect.top && v < textRect.bottom) {
- r.top = v + (lineHeight >> 1);
- r.bottom = r.top + 1;
- r.left = 0;
- r.right = windWidth - 15;
- DrawGrayRect(&r);
- }
- v += lineHeight;
- }
- if (v >= textRect.top && v < textRect.bottom) {
- if (f->labelKind == kMsgFieldLabelLeft) {
- labelWidth = StringWidth(f->label);
- r = (**edit).viewRect;
- r.right = r.left;
- r.left = 0;
- TETextBox(f->label+1, *f->label, &r, teFlushRight);
- } else if (f->labelKind == kMsgFieldLabelTop) {
- MoveTo(kTextMargin, v + fInfo.leading + fInfo.ascent);
- TextFace(italic);
- DrawString(f->label);
- TextFace(0);
- }
- }
- TEUpdate(&wind->portRect, edit);
- }
- MyHSetState(fields, state);
- }
-
-
-
- /*----------------------------------------------------------------------------
- Mouse
-
- Handle a mouse down event in the content area of a message window.
-
- Entry: wind = pointer to message window.
- where = location of mouse down in local coords.
- modifiers = modifiers field from event record.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr Mouse (WindowPtr wind, Point where, short modifiers)
- {
- TWindow **info;
- short part, dv, oldVal;
- ControlHandle control;
- Rect r, iconRect;
- Boolean iconClick = false;
- Boolean changeDisplayedFields = false;
- TEHandle edit;
- OSErr err = noErr;
- short iconID;
- Boolean dragged = false, trashed, extraSpaceDeleted;
- short fieldIndex;
- short oldSelStart, oldSelEnd;
-
- info = (TWindow**)GetWRefCon(wind);
-
- part = FindControl(where, wind, &control);
- if (part != 0) {
- if (control == (**info).sendButton) {
- if (TrackControl(control, where, nil) != 0) {
- err = SendMessageAndCloseWindow(wind);
- if (err != noErr) return err;
- }
- } else if (control == (**info).vScroll) {
- if (part == inThumb) {
- oldVal = GetControlValue(control);
- TrackControl(control, where, nil);
- dv = GetControlValue(control) - oldVal;
- if (dv != 0) Scroll(wind, -dv);
- } else {
- SetControlReference(control, 0);
- TrackControl(control, where, gScrollActionUPP);
- SetControlReference(control, 1);
- AdjustScrollMax(wind);
- }
- } else if (TrackControl(control, where, nil) != 0) {
- oldVal = GetControlValue(control);
- SetControlValue(control, 1 - oldVal);
- if (control == (**info).tabCheckbox) {
- (**info).tabEnabled = oldVal == 0;
- KillBalloon();
- } else if (control == (**info).wrapCheckbox) {
- (**info).wrapOnSend = oldVal == 0;
- KillBalloon();
- }
- (**info).changed = true;
- }
- } else if (where.v < (**info).iconPanelHeight) {
- SetRect(&iconRect, kNewsIconH, kIconV, kNewsIconH + 32, kIconV + 32);
- if ((**info).showLabels) {
- SetRect(&r, kNewsIconH - 24, 0,
- kNewsIconH + 52, (**info).iconPanelHeight - 3);
- } else {
- SetRect(&r, kNewsIconH - kCheckMarkDeltaH, 0,
- kNewsIconH + 32, (**info).iconPanelHeight - 3);
- }
- if (PtInRect(where, &r)) {
- iconClick = true;
- iconID = kNewsIconID;
- } else {
- OffsetRect(&r, kMailIconH - kNewsIconH, 0);
- OffsetRect(&iconRect, kMailIconH - kNewsIconH, 0);
- if (PtInRect(where, &r)) {
- iconClick = true;
- iconID = kMailIconID;
- } else {
- OffsetRect(&r, kSelfIconH - kMailIconH, 0);
- OffsetRect(&iconRect, kSelfIconH - kMailIconH, 0);
- if (PtInRect(where, &r)) {
- iconClick = true;
- iconID = kSelfIconID;
- }
- }
- }
- if (iconClick && TrackIconClick(where, &iconRect, &r, iconID)) {
- switch (iconID) {
- case kNewsIconID:
- (**info).newsIcon = !(**info).newsIcon;
- changeDisplayedFields = true;
- break;
- case kMailIconID:
- (**info).mailIcon = !(**info).mailIcon;
- changeDisplayedFields = true;
- break;
- case kSelfIconID:
- (**info).selfIcon = !(**info).selfIcon;
- changeDisplayedFields = false;
- break;
- }
- KillBalloon();
- r = iconRect;
- r.left -= kCheckMarkDeltaH;
- r.right = iconRect.left - 1;
- InvalRect(&r);
- HiliteControl((**info).sendButton,
- (**info).newsIcon || (**info).mailIcon || (**info).selfIcon ? 0 : 255);
- if (changeDisplayedFields) ChangeDisplayedFields(wind);
- (**info).changed = true;
- }
- } else {
- edit = FindFieldContainingPoint(wind, where, &fieldIndex);
- if (edit != nil) {
- if (gHaveDragMgr) {
- err = DragText(&gCurEvent, where, edit, &dragged, &trashed);
- if (err != noErr) return err;
- }
- if (wind == FrontWindow() && !dragged) {
- if (fieldIndex != (**info).curField) {
- ChangeCurField(wind, fieldIndex);
- modifiers = 0;
- }
- oldSelStart = (**edit).selStart;
- oldSelEnd = (**edit).selEnd;
- MyTEClick(where, (modifiers & shiftKey) != 0, edit);
- if (fieldIndex >= (**info).firstScrollingField) {
- err = CommandClick(wind, edit, oldSelStart, oldSelEnd, modifiers);
- if (err != noErr) return err;
- }
- } else if (trashed) {
- MyTEDelete(edit, false, &extraSpaceDeleted);
- AdjustFieldHeight(wind, edit);
- (**info).changed = true;
- }
- }
- }
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- Draggable
-
- Determine whether a mouse down event is on a draggable object in a
- message window.
-
- Entry: wind = pointer to message window.
- where = location of mouse down event, in local coordinates.
- modifiers = modifiers field from event record.
-
- Exit: function result = true if object is draggable.
- ----------------------------------------------------------------------------*/
-
- static Boolean Draggable (WindowPtr wind, Point where, short modifiers)
- {
- TWindow **info;
- TMsgFieldInfo **fields;
- short curField;
- TEHandle edit;
-
- info = (TWindow**)GetWRefCon(wind);
- fields = (**info).fields;
- curField = (**info).curField;
- edit = (*fields)[curField].edit;
- return PtInTEHiliteRgn(where, edit);
- }
-
-
-
- /*----------------------------------------------------------------------------
- Key
-
- Handle a key down event for a message window.
-
- Entry: wind = pointer to message window.
- theChar = ASCII code of key.
- theKey = keyboard code of key.
- modifiers = modifiers field from event record.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr Key (WindowPtr wind, unsigned char theChar, unsigned char theKey,
- short modifiers)
- {
- TWindow **info;
- TMsgFieldInfo **fields;
- TEHandle edit;
- short curField, numFields;
- short selStart, selEnd, teLength;
- Handle text;
- short h;
- Rect r;
- short numSpace;
- char *p;
- short col;
- Boolean shift, option, command, tabEnabled;
- ControlHandle vScroll;
- short tabStops;
- long maxLen;
- Boolean isTabField, isQuoteStringField, isBodyField, isSigField, isArrow;
- OSErr err = noErr;
- Boolean extraSpaceDeleted;
- short scrollIntoView;
-
- shift = (modifiers & shiftKey) != 0;
- option = (modifiers & optionKey) != 0;
- command = (modifiers & cmdKey) != 0;
-
- info = (TWindow**)GetWRefCon(wind);
- vScroll = (**info).vScroll;
- fields = (**info).fields;
- curField = (**info).curField;
- numFields = (**info).numFields;
- tabEnabled = (**info).tabEnabled;
- tabStops = (**info).tabStops;
- edit = (*fields)[curField].edit;
- selStart = (**edit).selStart;
- selEnd = (**edit).selEnd;
- teLength = (**edit).teLength;
- text = (**edit).hText;
-
- isTabField = edit == (**info).tabField;
- isQuoteStringField = edit == (**info).quoteStringField;
- isBodyField = edit == (**info).theTE;
- isSigField = edit == (**info).signatureField;
- isArrow = IsArrowKey(theChar);
-
- if (command) {
- if (theChar == '1' || theChar == '2' || theChar == '3') {
- switch (theChar) {
- case '1':
- (**info).newsIcon = !(**info).newsIcon;
- h = kNewsIconH;
- ChangeDisplayedFields(wind);
- break;
- case '2':
- (**info).mailIcon = !(**info).mailIcon;
- ChangeDisplayedFields(wind);
- h = kMailIconH;
- break;
- case '3':
- (**info).selfIcon = !(**info).selfIcon;
- h = kSelfIconH;
- break;
- }
- SetRect(&r, h - kCheckMarkDeltaH, kIconV, h - 1, kIconV + 32);
- InvalRect(&r);
- HiliteControl((**info).sendButton,
- (**info).newsIcon || (**info).mailIcon || (**info).selfIcon ? 0 : 255);
- (**info).changed = true;
- KillBalloon();
- return noErr;
- } else if (!isArrow) {
- SysBeep(0);
- return noErr;
- }
- }
-
- /* Note: The following code has been commented out to disable the keypad shortcuts
- in message windows, at the request of J.P. Kuypers, who would like to use the
- keypad to type numbers on his Azerty keyboard. If anyone complains, I can add
- a new pref for this. */
-
- /*
- if (gPrefs.keypadShortcuts && IsKeypadKey(theChar, theKey, &keypadKey)) {
- switch (keypadKey) {
- case kKeypadEqualKey:
- DoSelectAll(wind);
- return noErr;
- case kKeypadStarKey:
- return DoClose(wind);
- case kKeypad1Key:
- ScrollAction(vScroll, kScrollToEnd);
- return noErr;
- case kKeypad2Key:
- ScrollAction(vScroll, inDownButton);
- return noErr;
- case kKeypad3Key:
- ScrollAction(vScroll, inPageDown);
- return noErr;
- case kKeypad7Key:
- ScrollAction(vScroll, kScrollToHome);
- return noErr;
- case kKeypad8Key:
- ScrollAction(vScroll, inUpButton);
- return noErr;
- case kKeypad9Key:
- ScrollAction(vScroll, inPageUp);
- return noErr;
- default:
- SysBeep(0);
- return noErr;
- }
- }
- */
-
- if (theChar == 0x0C && theKey != 0x79 && (modifiers & controlKey) != 0) {
- /* Control-L */
- DoInsertSpoilerCharacter(wind);
- return noErr;
- }
-
- if (theChar == pageUpKey) {
- ScrollAction(vScroll, inPageUp);
- return noErr;
- }
- if (theChar == pageDownKey) {
- ScrollAction(vScroll, inPageDown);
- return noErr;
- }
- if (theChar == homeKey) {
- ScrollAction(vScroll, kScrollToHome);
- return noErr;
- }
- if (theChar == endKey) {
- ScrollAction(vScroll, kScrollToEnd);
- return noErr;
- }
-
- if (theChar == forwardDelKey) {
- if (selStart < selEnd) {
- theChar = deleteKey;
- } else if (selEnd < teLength) {
- (**edit).selEnd = selEnd + 1;
- TEDelete(edit);
- goto exit1;
- } else {
- SysBeep(0);
- return noErr;
- }
- }
-
- if (theChar == deleteKey && selStart < selEnd) {
- MyTEDelete(edit, false, &extraSpaceDeleted);
- goto exit1;
- }
-
- if (theChar == tabKey) {
- if (tabEnabled && !shift && !option && (isBodyField || isSigField)) {
- if (tabStops == 0) {
- numSpace = 1;
- } else {
- p = *text + selStart - 1;
- col = 0;
- while (p >= *text && *p != CR) {
- p--;
- col++;
- }
- numSpace = tabStops - (col % tabStops);
- }
- if ((long)(**edit).teLength - (long)(**edit).selEnd +
- (long)(**edit).selStart + numSpace > 0x7fff) goto exit2;
- while (numSpace--) TEKey(' ', edit);
- goto exit1;
- } else {
- if (shift) {
- curField--;
- if (curField < 0) curField = numFields - 1;
- } else {
- curField++;
- if (curField >= numFields) curField = 0;
- }
- edit = (*fields)[curField].edit;
- TESetSelect(0, 0x7fff, edit);
- ChangeCurField(wind, curField);
- ScrollSelectionIntoView(wind);
- return noErr;
- }
- }
-
- if (theChar != deleteKey && !isArrow) {
- if (!isPrintable(theChar) && theChar != CR ||
- theChar == CR && (isTabField || isQuoteStringField) ||
- isTabField && !(theChar >= '0' && theChar <= '9'))
- {
- SysBeep(0);
- return noErr;
- }
- }
-
- maxLen = isTabField ? 2 : isQuoteStringField ? 11 : 0x7fff;
- if (isPrintable(theChar) || theChar == CR) {
- if ((long)(**edit).teLength - (long)(**edit).selEnd +
- (long)(**edit).selStart + 1 > maxLen) goto exit2;
- }
-
- if (isArrow) {
- TEArrowKey(theChar, modifiers, edit, GetPageHeight(wind), &gPrevEvent,
- &scrollIntoView);
- ScrollRangeIntoView(wind, scrollIntoView, scrollIntoView);
- } else {
- TEKey(theChar, edit);
- }
-
- exit1:
-
- if (!isArrow) {
- AdjustCurFieldHeight(wind);
- (**info).changed = true;
- }
- return noErr;
-
- exit2:
-
- if (!isTabField && !isQuoteStringField) {
- ErrorMessageNumber(kStrNoMoreChars);
- } else {
- ErrorMessageNumber(kStrNoMoreTyping);
- }
- return userCanceledErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- Grow
-
- Handle a mouse down event in the grow box of a message window.
-
- Entry: wind = pointer to message window.
- where = location of mouse down event, in global coordinates.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr Grow (WindowPtr wind, Point where)
- {
- Rect sizeRect;
- long size;
- short width, height;
- TWindow **info;
-
- SetRect(&sizeRect, MinWidth(wind), MinHeight(wind), 0x7fff, 0x7fff);
- size = GrowWindow(wind, where, &sizeRect);
-
- if (size != 0) {
- width = LoWord(size);
- height = HiWord(size);
- FixHeight(wind, &height);
- SizeWindow(wind, width, height, false);
- ResizeContents(wind);
- info = (TWindow**)GetWRefCon(wind);
- (**info).windPosValid = true;
- (**info).movedSinceLastSave = true;
- }
-
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- Zoom
-
- Zoom a message window.
-
- Entry: wind = pointer to message window.
- zoomDir = zoom direction = inZoomIn or inZoomOut.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr Zoom (WindowPtr wind, short zoomDir)
- {
- TWindow **info;
- short width, height;
- Rect zoomRect;
- WStateData **wState;
-
- info = (TWindow**)GetWRefCon(wind);
- wState = (WStateData**)((WindowPeek)wind)->dataHandle;
- if (zoomDir == inZoomOut) {
- width = 80*CharWidth('W') + 2*kTextMargin + 18;
- height = 0x7fff;
- CalculateZoomRect(wind, width, height, &zoomRect, gPrefs.dontCoverFinderIcons);
- height = zoomRect.bottom - zoomRect.top;
- FixHeight(wind, &height);
- zoomRect.bottom = zoomRect.top + height;
- (**wState).stdState = zoomRect;
- if (WindRectEqualRect(wind, &zoomRect)) return noErr;
- }
-
- EraseRect(&wind->portRect);
- ZoomWindow(wind, zoomDir, false);
- ResizeContents(wind);
- (**info).windPosValid = true;
- (**info).movedSinceLastSave = true;
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- Command
-
- Handle a command for a message window.
-
- Entry: wind = pointer to message window.
- menu = the menu.
- item = the item.
- modifiers = modifiers field from event record.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr Command (WindowPtr wind, short menu, short item, short modifiers)
- {
- OSErr err = noErr;
-
- switch (menu) {
-
- case kFileMenu:
-
- switch (item) {
- case kSaveItem:
- err = DoSave(wind, modifiers);
- break;
- case kSaveAsItem:
- err = DoSaveAs(wind);
- break;
- case kPrintItem:
- err = DoPrint(wind, modifiers);
- break;
- }
- break;
-
- case kEditMenu:
-
- switch (item) {
- case kCutItem:
- DoCut(wind);
- break;
- case kCopyItem:
- DoCopy(wind);
- break;
- case kPasteItem:
- err = DoPaste(wind, (modifiers & shiftKey) != 0);
- break;
- case kPasteAsQuotationItem:
- DoPaste(wind, true);
- break;
- case kClearItem:
- DoClear(wind);
- break;
- case kSelectAllItem:
- DoSelectAll(wind);
- break;
- case kFindItem:
- err = DoFind(wind);
- break;
- case kFindAgainItem:
- err = DoFindAgain(wind);
- break;
- case kEnterSelectionItem:
- err = DoEnterSelection(wind);
- break;
- case kShowHideDetailsItem:
- DoShowHideDetails(wind);
- break;
- case kRot13Item:
- DoRot13(wind);
- break;
- case kInsertSpoilerCharacterItem:
- DoInsertSpoilerCharacter(wind);
- break;
- case kWrapItem:
- DoWrap(wind);
- break;
- case kUnwrapItem:
- DoUnwrap(wind);
- break;
- }
- break;
-
- case kNewsMenu:
-
- switch (item) {
- case kSendMessageItem:
- err = DoSendMessage(wind);
- break;
- }
- break;
- }
-
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- Close
-
- Close a message window.
-
- Entry: wind = pointer to message window.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr Close (WindowPtr wind)
- {
- TWindow **info;
- DialogPtr dlg = nil;
- short item;
- OSErr err = noErr;
-
- info = (TWindow**)GetWRefCon(wind);
-
- if ((**info).changed) {
- err = MyGetNewDialog(kAskSendOrSaveAlert, 1, 3, &dlg);
- if (err != noErr) return err;
- SetItemKeyEquivalent(dlg, 2, 'S');
- SetItemKeyEquivalent(dlg, 4, 'D');
- SysBeep(0);
- MyModalDialog(dlg, gDialogFilterUPP, &item);
- err = DoClose(dlg);
- if (err != noErr) return err;
-
- switch (item) {
- case 1: /* send */
- err = SendMessage(wind);
- if (err != noErr) return err;
- break;
- case 2: /* save */
- err = DoSave(wind, 0);
- if (err != noErr) return err;
- break;
- case 3: /* cancel */
- return userCanceledErr;
- case 4: /* discard */
- break;
- }
- }
-
- err = SaveWindPosToFile(wind);
- if (err != noErr) return err;
-
- if ((**info).theTE != nil) TEDispose((**info).theTE);
- if ((**info).tabField != nil) TEDispose((**info).tabField);
- if ((**info).quoteStringField != nil) TEDispose((**info).quoteStringField);
- if ((**info).newsgroupsField != nil) TEDispose((**info).newsgroupsField);
- if ((**info).toField != nil) TEDispose((**info).toField);
- if ((**info).subjectField != nil) TEDispose((**info).subjectField);
- if ((**info).ccField != nil) TEDispose((**info).ccField);
- if ((**info).bccField != nil) TEDispose((**info).bccField);
- if ((**info).replytoField != nil) TEDispose((**info).replytoField);
- if ((**info).followuptoField != nil) TEDispose((**info).followuptoField);
- if ((**info).keywordsField != nil) TEDispose((**info).keywordsField);
- if ((**info).distributionField != nil) TEDispose((**info).distributionField);
- if ((**info).extraNewsField != nil) TEDispose((**info).extraNewsField);
- if ((**info).extraMailField != nil) TEDispose((**info).extraMailField);
- if ((**info).signatureField != nil) TEDispose((**info).signatureField);
- MyDisposeHandle((**info).references);
- MyDisposeHandle((**info).from);
- MyDisposeHandle((**info).fields);
- MyDisposeHandle((**info).alias);
- MyDisposeHandle(info);
-
- if (gHaveDragMgr) {
- RemoveTrackingHandler(gHandleTrackingUPP, wind);
- RemoveReceiveHandler(gHandleReceiveUPP, wind);
- }
-
- MyDisposeWindow(wind);
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- Idle
-
- Handle idle time tasks for a message window.
-
- Entry: wind = pointer to message window.
-
- Exit: cursorRgn = cursor region for WaitNextEvent mouse moved events.
- ----------------------------------------------------------------------------*/
-
- static void Idle (WindowPtr wind, RgnHandle cursorRgn)
- {
- TWindow **info;
- short curField;
- TEHandle edit, tempEdit;
- TMsgFieldInfo **fields, *f;
- short numFields, i;
- Rect r;
- static RgnHandle rgn = nil;
- Point where;
- unsigned long fileEnabled, editEnabled, specialEnabled;
- char state;
- short selStart, selEnd;
-
- info = (TWindow**)GetWRefCon(wind);
- fields = (**info).fields;
- curField = (**info).curField;
- numFields = (**info).numFields;
- edit = (*fields)[curField].edit;
- TEIdle(edit);
-
- if (rgn == nil) rgn = NewRgn();
- SetEmptyRgn(cursorRgn);
- state = MyHGetState(fields);
- MyHLock(fields);
- for (i = 0, f = *fields; i < numFields; i++, f++) {
- tempEdit = f->edit;
- r = (**tempEdit).viewRect;
- InsetRect(&r, -kTextMargin, 0);
- LocalToGlobalRect(&r);
- RectRgn(rgn, &r);
- UnionRgn(rgn, cursorRgn, cursorRgn);
- }
- MyHSetState(fields, state);
- if (gHaveDragMgr) SubtractTEHiliteRgn(cursorRgn, edit);
-
- GetMouse(&where);
- LocalToGlobal(&where);
-
- if (PtInRgn(where, cursorRgn)) {
- SetCursor(&gIBeamCurs);
- } else {
- SetCursor(&qd.arrow);
- ComplementRgn(cursorRgn);
- }
-
- fileEnabled = kMessageFileEnabled;
- if ((**info).alias != nil && !(**info).changed)
- fileEnabled &= ~kSaveMask;
- editEnabled = kMessageEditEnabled;
- selStart = (**edit).selStart;
- selEnd = (**edit).selEnd;
- if (selStart >= selEnd) {
- editEnabled &= ~(kCutMask | kCopyMask | kClearMask |
- kEnterSelectionMask | kRot13Mask | kWrapMask | kUnwrapMask);
- } else if (selEnd > selStart + 255) {
- editEnabled &= ~kEnterSelectionMask;
- }
- if (MyTEGetScrapLen() == 0)
- editEnabled &= ~(kPasteMask | kPasteAsQuotationMask);
- if (edit != (**info).theTE)
- editEnabled &= ~(kPasteAsQuotationMask | kInsertSpoilerCharacterMask |
- kRot13Mask | kWrapMask | kUnwrapMask);
- if ((**edit).teLength == 0)
- editEnabled &= ~kSelectAllMask;
- specialEnabled = kMessageSpecialEnabled;
- if (*gFindPattern == 0) editEnabled &= ~kFindAgainMask;
- SetMenusTo(kAppleAllEnabled, fileEnabled, editEnabled,
- kMessageNewsEnabled, specialEnabled, kMessageWindEnabled);
- SetEditMenuShowHideDetails(!(**info).showDetails);
- }
-
-
-
- /*----------------------------------------------------------------------------
- Help
-
- Handle help balloons for a message window.
-
- Entry: wind = pointer to message window.
- where = current mouse location in local coordinates.
- ----------------------------------------------------------------------------*/
-
- static void Help (WindowPtr wind, Point where)
- {
- TWindow **info;
- short iconPanelHeight, panelHeight, index, lastIconRight, fieldIndex;
- Rect r, textRect;
- Boolean inIcon = false, checked;
- Point tip = {0, 0};
- ControlHandle sendButton, tabCheckbox, wrapCheckbox;
- TEHandle tabField, quoteStringField, field;
-
- if (DoSizeBoxAndVerticalScrollBarBalloons(wind, where)) return;
- info = (TWindow**)GetWRefCon(wind);
- iconPanelHeight = (**info).iconPanelHeight;
- panelHeight = (**info).panelHeight;
- if (where.v < iconPanelHeight) {
- if ((**info).showLabels) {
- SetRect(&r, kNewsIconH - 24, 0,
- kNewsIconH + 52, iconPanelHeight - 3);
- } else {
- SetRect(&r, kNewsIconH - kCheckMarkDeltaH, 0,
- kNewsIconH + 32, iconPanelHeight - 3);
- }
- lastIconRight = r.right + kSelfIconH - kNewsIconH;
- if (PtInRect(where, &r)) {
- inIcon = true;
- index = 46;
- checked = (**info).newsIcon;
- } else {
- OffsetRect(&r, kMailIconH - kNewsIconH, 0);
- if (PtInRect(where, &r)) {
- inIcon = true;
- index = 48;
- checked = (**info).mailIcon;
- } else {
- OffsetRect(&r, kSelfIconH - kMailIconH, 0);
- if (PtInRect(where, &r)) {
- inIcon = true;
- index = 50;
- checked = (**info).selfIcon;
- }
- }
- }
- if (inIcon) {
- ShowHelpBalloon(tip, &r, checked ? index : index + 1);
- return;
- }
- sendButton = (**info).sendButton;
- r = (**sendButton).contrlRect;
- if (PtInRect(where, &r)) {
- ShowHelpBalloon(tip, &r, (**sendButton).contrlHilite == 0 ? 52 : 53);
- return;
- }
- SetRect(&r, lastIconRight, 0, (**sendButton).contrlRect.left, iconPanelHeight);
- if (PtInRect(where, &r)) {
- ShowHelpBalloon(tip, &r, 54);
- return;
- }
- } else if ((**info).showDetails && where.v < panelHeight) {
- tabCheckbox = (**info).tabCheckbox;
- r = (**tabCheckbox).contrlRect;
- if (PtInRect(where, &r)) {
- SetPt(&tip, r.left + 5, r.top + 8);
- ShowHelpBalloon(tip, &r, (**tabCheckbox).contrlValue == 0 ? 55 : 56);
- return;
- }
- wrapCheckbox = (**info).wrapCheckbox;
- r = (**wrapCheckbox).contrlRect;
- if (PtInRect(where, &r)) {
- SetPt(&tip, r.left + 5, r.top + 8);
- ShowHelpBalloon(tip, &r, (**wrapCheckbox).contrlValue == 0 ? 57 : 58);
- return;
- }
- tabField = (**info).tabField;
- r = (**tabField).viewRect;
- if (PtInRect(where, &r)) {
- ShowHelpBalloon(tip, &r, 59);
- return;
- }
- quoteStringField = (**info).quoteStringField;
- r = (**quoteStringField).viewRect;
- if (PtInRect(where, &r)) {
- ShowHelpBalloon(tip, &r, 60);
- return;
- }
- } else {
- field = FindFieldContainingPoint(wind, where, &fieldIndex);
- if (field != nil) {
- if (field == (**info).newsgroupsField) {
- index = 61;
- } else if (field == (**info).toField) {
- index = 62;
- } else if (field == (**info).subjectField) {
- index = 63;
- } else if (field == (**info).ccField) {
- index = 64;
- } else if (field == (**info).bccField) {
- index = 65;
- } else if (field == (**info).replytoField) {
- index = 66;
- } else if (field == (**info).followuptoField) {
- index = 67;
- } else if (field == (**info).keywordsField) {
- index = 68;
- } else if (field == (**info).distributionField) {
- index = 69;
- } else if (field == (**info).extraNewsField) {
- index = 70;
- } else if (field == (**info).extraMailField) {
- index = 71;
- } else if (field == (**info).signatureField) {
- index = 72;
- } else if (field == (**info).theTE) {
- index = 73;
- }
- GetTextRect(wind, &textRect);
- r = (**field).viewRect;
- SectRect(&textRect, &r, &r);
- if (PtInRect(where, &r)) {
- SetPt(&tip, r.left + 3, r.top + 3);
- ShowHelpBalloon(tip, &r, index);
- return;
- }
- }
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- InitMessageDispatchTable
-
- Initialize the dispatch table for message windows.
- ----------------------------------------------------------------------------*/
-
- void InitMessageDispatchTable (void)
- {
- TDispatch *d;
-
- d = &gDispatch[kMessage];
-
- d->activate = Activate;
- d->update = Update;
- d->mouse = Mouse;
- d->draggable = Draggable;
- d->key = Key;
- d->grow = Grow;
- d->zoom = Zoom;
- d->command = Command;
- d->close = Close;
- d->idle = Idle;
- d->help = Help;
-
- gAutoScrollUPP = NewTEClickLoopProc(AutoScroll);
- gHandleTrackingUPP = NewDragTrackingHandlerProc(HandleTracking);
- gHandleReceiveUPP = NewDragReceiveHandlerProc(HandleReceive);
- gScrollActionUPP = NewControlActionProc(ScrollAction);
- }
-